diff options
219 files changed, 2996 insertions, 3303 deletions
diff --git a/cmake/QtCreatorIDEBranding.cmake b/cmake/QtCreatorIDEBranding.cmake index f7327d19fa..63581b9720 100644 --- a/cmake/QtCreatorIDEBranding.cmake +++ b/cmake/QtCreatorIDEBranding.cmake @@ -1,9 +1,9 @@ #BINARY_ARTIFACTS_BRANCH = master #PROJECT_USER_FILE_EXTENSION = .user -set(IDE_VERSION "4.9.83") # The IDE version. -set(IDE_VERSION_COMPAT "4.9.83") # The IDE Compatibility version. -set(IDE_VERSION_DISPLAY "4.10.0-beta2") # The IDE display version. +set(IDE_VERSION "4.10.82") # The IDE version. +set(IDE_VERSION_COMPAT "4.10.82") # The IDE Compatibility version. +set(IDE_VERSION_DISPLAY "4.11.0-beta1") # The IDE display version. set(IDE_COPYRIGHT_YEAR "2019") # The IDE copyright year. set(IDE_SETTINGSVARIANT "QtProject") # The IDE settings variation. diff --git a/doc/config/qtcreator-project.qdocconf b/doc/config/qtcreator-project.qdocconf index db7d38dc39..4ab5505f76 100644 --- a/doc/config/qtcreator-project.qdocconf +++ b/doc/config/qtcreator-project.qdocconf @@ -19,7 +19,7 @@ imagedirs = ../images \ ../../src/plugins/qmldesigner/components/componentcore/images \ ../../src/plugins/qmldesigner/components/formeditor \ ../../src/plugins/qmldesigner/components/navigator \ - ../../src/plugins/qmldesigner//qmldesignerextension/timelineeditor/images \ + ../../src/plugins/qmldesigner/components/timelineeditor/images \ ../../src/plugins/scxmleditor/common/images \ ../../src/plugins/texteditor/images \ ../../src/plugins/valgrind/images diff --git a/doc/src/editors/creator-only/creator-compilation-database.qdocinc b/doc/src/editors/creator-only/creator-compilation-database.qdocinc index b1481f561d..b12b59dd70 100644 --- a/doc/src/editors/creator-only/creator-compilation-database.qdocinc +++ b/doc/src/editors/creator-only/creator-compilation-database.qdocinc @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2018 The Qt Company Ltd. +** Copyright (C) 2019 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the Qt Creator documentation. @@ -40,10 +40,20 @@ To generate a compilation database from the information that the code model has, select \uicontrol Build > \uicontrol {Generate Compilation Database}. + You can add files, such as non-C files, to the project in + \e {compile_database.json.files}. + You can use the experimental Compilation Database Project Manager to open the files in a compilation database with access to all the editing features provided by the Clang code model. + To switch between header and source files, select \uicontrol Tools > + \uicontrol C++ > \uicontrol {Switch Header/Source}. + + You can specify custom build steps and run settings for compilation + database projects in the \uicontrol Projects mode. For more information, + see \l{Adding Custom Build Steps} and \l {Specifying Run Settings}. + To enable the plugin, select \uicontrol Help > \uicontrol {About Plugins} > \uicontrol {Build Systems} > \uicontrol {Compilation Database Project Manager}. Then restart \QC to load the plugin. diff --git a/doc/src/qtquick/qtquick-connection-editor-properties.qdoc b/doc/src/qtquick/qtquick-connection-editor-properties.qdoc index 7b6168dc78..651c224a18 100644 --- a/doc/src/qtquick/qtquick-connection-editor-properties.qdoc +++ b/doc/src/qtquick/qtquick-connection-editor-properties.qdoc @@ -31,10 +31,19 @@ \title Specifying Dynamic Properties - You can bind object properties to dynamic expressions to define global - properties for an object that can be read by other objects. For example, - you can specify global properties for the root object that you can use in - the child objects. + In addition to the properties predefined for QML types, you can specify + \e {dynamic properties} to add properties that would not otherwise + exist for a particular type. You bind the properties to dynamic expressions + to define global properties for an object that can be read by other objects. + For example, you can specify global properties for the root object that you + can use in the child objects. + + For example, to specify spacing between UI elements, you could define a + margin for an object of a QML type that does not have a margin property, + and then use bindings to refer to the value of the margin property from + other objects. + + Similarly, you can add dynamic properties at component level. You can specify dynamic properties for objects in the \uicontrol Connections view. @@ -55,7 +64,7 @@ \li Double-click the value in the \uicontrol {Property Type} column to specify the type of the property. \li Double-click the value in the \uicontrol {Property Value} column - to specify the value of the property. + to specify a dynamic expression as the value of the property. \endlist */ diff --git a/qbs/imports/QtcProduct.qbs b/qbs/imports/QtcProduct.qbs index a031474c29..e54dc667f4 100644 --- a/qbs/imports/QtcProduct.qbs +++ b/qbs/imports/QtcProduct.qbs @@ -34,14 +34,18 @@ Product { // because conflicting scalar values would be reported (QBS-1225 would fix that). cpp.minimumMacosVersion: project.minimumMacosVersion - Properties { - condition: qbs.toolchain.contains("gcc") && !qbs.toolchain.contains("clang") - cpp.cxxFlags: base.concat(["-Wno-noexcept-type"]) - } - Properties { - condition: qbs.toolchain.contains("msvc") - cpp.cxxFlags: base.concat(["/w44996"]) + cpp.cxxFlags: { + var flags = []; + if (qbs.toolchain.contains("gcc") && !qbs.toolchain.contains("clang")) { + flags.push("-Wno-noexcept-type"); + if (Utilities.versionCompare(cpp.compilerVersion, "9") >= 0) + flags.push("-Wno-deprecated-copy", "-Wno-init-list-lifetime"); + } else if (qbs.toolchain.contains("msvc")) { + flags.push("/w44996"); + } + return flags; } + cpp.cxxLanguageVersion: "c++14" cpp.defines: qtc.generalDefines cpp.minimumWindowsVersion: "6.1" diff --git a/share/qtcreator/debugger/qttypes.py b/share/qtcreator/debugger/qttypes.py index 77cb2fa512..95217cf3b9 100644 --- a/share/qtcreator/debugger/qttypes.py +++ b/share/qtcreator/debugger/qttypes.py @@ -227,7 +227,10 @@ def qdump__QStandardItemData(d, value): def qdump__QStandardItem(d, value): vtable, dptr = value.split('pp') - vtable1, model, parent, values, children, rows, cols, item = d.split('pppPPIIp', dptr) + if d.isMsvcTarget(): + model, parent, values, children, rows, cols, item = d.split('ppPPIIp', dptr) + else: + vtable1, model, parent, values, children, rows, cols, item = d.split('pppPPIIp', dptr) d.putValue(' ') d.putNumChild(1) if d.isExpanded(): @@ -396,8 +399,7 @@ def qdump__QDateTime(d, value): def qdump__QDir(d, value): - if not d.isMsvcTarget(): - d.putNumChild(1) + d.putNumChild(1) privAddress = d.extractPointer(value) bit32 = d.ptrSize() == 4 qt5 = d.qtVersion() >= 0x050000 @@ -468,21 +470,22 @@ def qdump__QDir(d, value): absoluteDirEntryOffset = dirEntryOffset + fileSystemEntrySize d.putStringValue(privAddress + dirEntryOffset) - if d.isExpanded() and not d.isMsvcTarget(): + if d.isExpanded(): with Children(d): - ns = d.qtNamespace() - d.call('int', value, 'count') # Fill cache. - #d.putCallItem('absolutePath', '@QString', value, 'absolutePath') - #d.putCallItem('canonicalPath', '@QString', value, 'canonicalPath') - with SubItem(d, 'absolutePath'): - typ = d.lookupType(ns + 'QString') - d.putItem(d.createValue(privAddress + absoluteDirEntryOffset, typ)) - with SubItem(d, 'entryInfoList'): - typ = d.lookupType(ns + 'QFileInfo') - qdumpHelper_QList(d, privAddress + fileInfosOffset, typ) - with SubItem(d, 'entryList'): - typ = d.lookupType(ns + 'QStringList') - d.putItem(d.createValue(privAddress + filesOffset, typ)) + if not d.isMsvcTarget(): + ns = d.qtNamespace() + d.call('int', value, 'count') # Fill cache. + #d.putCallItem('absolutePath', '@QString', value, 'absolutePath') + #d.putCallItem('canonicalPath', '@QString', value, 'canonicalPath') + with SubItem(d, 'absolutePath'): + typ = d.lookupType(ns + 'QString') + d.putItem(d.createValue(privAddress + absoluteDirEntryOffset, typ)) + with SubItem(d, 'entryInfoList'): + typ = d.lookupType(ns + 'QFileInfo') + qdumpHelper_QList(d, privAddress + fileInfosOffset, typ) + with SubItem(d, 'entryList'): + typ = d.lookupType(ns + 'QStringList') + d.putItem(d.createValue(privAddress + filesOffset, typ)) d.putFields(value) diff --git a/share/qtcreator/debugger/stdtypes.py b/share/qtcreator/debugger/stdtypes.py index 3dfbe5bd8b..fb62135376 100644 --- a/share/qtcreator/debugger/stdtypes.py +++ b/share/qtcreator/debugger/stdtypes.py @@ -340,11 +340,12 @@ def qdump__std__multimap(d, value): return qdump__std__map(d, value) def qdumpHelper__std__tree__iterator(d, value, isSet=False): + treeTypeName = None if value.type.name.endswith("::iterator"): treeTypeName = value.type.name[:-len("::iterator")] elif value.type.name.endswith("::const_iterator"): treeTypeName = value.type.name[:-len("::const_iterator")] - treeType = d.lookupType(treeTypeName) + treeType = d.lookupType(treeTypeName) if treeTypeName else value.type[0] keyType = treeType[0] valueType = treeType[1] node = value["_M_node"].dereference() # std::_Rb_tree_node_base diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/nodeinstanceserver.cpp b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/nodeinstanceserver.cpp index a9a8111afd..56e407f62b 100644 --- a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/nodeinstanceserver.cpp +++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/nodeinstanceserver.cpp @@ -67,6 +67,8 @@ #include <tokencommand.h> #include <removesharedmemorycommand.h> +#include <utils/algorithm.h> + #include <QDebug> #include <QQmlEngine> #include <QQmlApplicationEngine> @@ -88,7 +90,10 @@ #include <algorithm> namespace { -bool testImportStatements(const QStringList &importStatementList, const QUrl &url, QString *errorMessage = 0) { + +bool testImportStatements(const QStringList &importStatementList, + const QUrl &url, QString *errorMessage = nullptr) +{ if (importStatementList.isEmpty()) return false; // ToDo: move engine outside of this function, this makes it expensive @@ -455,7 +460,7 @@ void NodeInstanceServer::setupImports(const QVector<AddImportContainer> &contain delete m_importComponent.data(); delete m_importComponentObject.data(); - const QStringList importStatementList(importStatementSet.toList()); + const QStringList importStatementList = Utils::toList(importStatementSet); const QStringList fullImportStatementList(QStringList(qtQuickImport) + importStatementList); // check possible import statements combinations diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5informationnodeinstanceserver.cpp b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5informationnodeinstanceserver.cpp index 9e0461ba29..99688fa7cc 100644 --- a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5informationnodeinstanceserver.cpp +++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5informationnodeinstanceserver.cpp @@ -60,6 +60,8 @@ #include <designersupportdelegate.h> +#include <utils/algorithm.h> + namespace QmlDesigner { Qt5InformationNodeInstanceServer::Qt5InformationNodeInstanceServer(NodeInstanceClientInterface *nodeInstanceClient) : @@ -166,13 +168,14 @@ void Qt5InformationNodeInstanceServer::collectItemChangesAndSendChangeCommands() sendTokenBack(); if (!informationChangedInstanceSet.isEmpty()) - nodeInstanceClient()->informationChanged(createAllInformationChangedCommand(informationChangedInstanceSet.toList())); + nodeInstanceClient()->informationChanged( + createAllInformationChangedCommand(Utils::toList(informationChangedInstanceSet))); if (!propertyChangedList.isEmpty()) nodeInstanceClient()->valuesChanged(createValuesChangedCommand(propertyChangedList)); if (!m_parentChangedSet.isEmpty()) { - sendChildrenChangedCommand(m_parentChangedSet.toList()); + sendChildrenChangedCommand(Utils::toList(m_parentChangedSet)); m_parentChangedSet.clear(); } diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5rendernodeinstanceserver.cpp b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5rendernodeinstanceserver.cpp index 8e221c9ea2..19160d9ea9 100644 --- a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5rendernodeinstanceserver.cpp +++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5rendernodeinstanceserver.cpp @@ -60,6 +60,8 @@ #include <designersupportdelegate.h> +#include <utils/algorithm.h> + namespace QmlDesigner { Qt5RenderNodeInstanceServer::Qt5RenderNodeInstanceServer(NodeInstanceClientInterface *nodeInstanceClient) : @@ -94,7 +96,7 @@ void Qt5RenderNodeInstanceServer::collectItemChangesAndSendChangeCommands() clearChangedPropertyList(); if (!m_dirtyInstanceSet.isEmpty()) { - nodeInstanceClient()->pixmapChanged(createPixmapChangedCommand(m_dirtyInstanceSet.toList())); + nodeInstanceClient()->pixmapChanged(createPixmapChangedCommand(Utils::toList(m_dirtyInstanceSet))); m_dirtyInstanceSet.clear(); } diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5testnodeinstanceserver.cpp b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5testnodeinstanceserver.cpp index ec90f0ce63..1f8540359b 100644 --- a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5testnodeinstanceserver.cpp +++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5testnodeinstanceserver.cpp @@ -62,6 +62,8 @@ #include <designersupportdelegate.h> +#include <utils/algorithm.h> + namespace QmlDesigner { Qt5TestNodeInstanceServer::Qt5TestNodeInstanceServer(NodeInstanceClientInterface *nodeInstanceClient) @@ -288,7 +290,8 @@ void QmlDesigner::Qt5TestNodeInstanceServer::collectItemChangesAndSendChangeComm clearChangedPropertyList(); if (!informationChangedInstanceSet.isEmpty()) { - InformationChangedCommand command = createAllInformationChangedCommand(informationChangedInstanceSet.toList()); + InformationChangedCommand command + = createAllInformationChangedCommand(Utils::toList(informationChangedInstanceSet)); command.sort(); nodeInstanceClient()->informationChanged(command); } @@ -299,7 +302,7 @@ void QmlDesigner::Qt5TestNodeInstanceServer::collectItemChangesAndSendChangeComm } if (!parentChangedSet.isEmpty()) - sendChildrenChangedCommand(parentChangedSet.toList()); + sendChildrenChangedCommand(Utils::toList(parentChangedSet)); } } diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/PropertyTemplates/ColorEditorTemplate.template b/share/qtcreator/qmldesigner/propertyEditorQmlSources/PropertyTemplates/ColorEditorTemplate.template index ad6e541ce9..2f61a2bfa6 100644 --- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/PropertyTemplates/ColorEditorTemplate.template +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/PropertyTemplates/ColorEditorTemplate.template @@ -1,5 +1,11 @@ +Section { + anchors.left: parent.left + anchors.right: parent.right + caption: "%1" + ColorEditor { backendValue: backendValues.%2 supportGradient: false } +} diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/PropertyTemplates/FontEditorTemplate.template b/share/qtcreator/qmldesigner/propertyEditorQmlSources/PropertyTemplates/FontEditorTemplate.template new file mode 100644 index 0000000000..8f12d7fff7 --- /dev/null +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/PropertyTemplates/FontEditorTemplate.template @@ -0,0 +1,7 @@ + +FontSection { + anchors.left: parent.left + anchors.right: parent.right + caption: "%1" + fontName: "%2" +} diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/PropertyTemplates/RectangleEditorTemplate.template b/share/qtcreator/qmldesigner/propertyEditorQmlSources/PropertyTemplates/RectangleEditorTemplate.template new file mode 100644 index 0000000000..bfa9790b59 --- /dev/null +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/PropertyTemplates/RectangleEditorTemplate.template @@ -0,0 +1,64 @@ +Section { + anchors.left: parent.left + anchors.right: parent.right + caption: qsTr("%2 Color") + + ColorEditor { + caption: qsTr("Color") + backendValue: backendValues.%2_color + supportGradient: true + } + + +} + +Section { + anchors.left: parent.left + anchors.right: parent.right + caption: qsTr("%2 Border Color") + + ColorEditor { + caption: qsTr("Border Color") + backendValue: backendValues.%2_border_color + supportGradient: false + } +} + + +Section { + anchors.left: parent.left + anchors.right: parent.right + caption: "%2 Rectangle" + + SectionLayout { + rows: 2 + Label { + text: qsTr("Border") + } + SecondColumnLayout { + SpinBox { + backendValue: backendValues.%2_border_width + hasSlider: true + Layout.preferredWidth: 120 + } + ExpandingSpacer { + + } + } + Label { + text: qsTr("Radius") + } + SecondColumnLayout { + SpinBox { + backendValue: backendValues.%2_radius + hasSlider: true + Layout.preferredWidth: 120 + minimumValue: 0 + maximumValue: Math.min(backendValues.height.value, backendValues.width.value) / 2 + } + ExpandingSpacer { + + } + } + } +} diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/PropertyTemplates/TemplateTypes.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/PropertyTemplates/TemplateTypes.qml index fd3fbfaee3..8917e81d5e 100644 --- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/PropertyTemplates/TemplateTypes.qml +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/PropertyTemplates/TemplateTypes.qml @@ -52,4 +52,23 @@ AutoTypes { sourceFile: "ColorEditorTemplate.template" separateSection: true } + + Type { + typeNames: ["Text"] + sourceFile: "TextEditorTemplate.template" + separateSection: true + } + + Type { + typeNames: ["font", "QFont"] + sourceFile: "FontEditorTemplate.template" + separateSection: true + } + + Type { + typeNames: ["Rectangle"] + sourceFile: "RectangleEditorTemplate.template" + separateSection: true + } + } diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/PropertyTemplates/TextEditorTemplate.template b/share/qtcreator/qmldesigner/propertyEditorQmlSources/PropertyTemplates/TextEditorTemplate.template new file mode 100644 index 0000000000..e9e8787f75 --- /dev/null +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/PropertyTemplates/TextEditorTemplate.template @@ -0,0 +1,105 @@ +Section { + anchors.left: parent.left + anchors.right: parent.right + caption: "%1" + + SectionLayout { + columns: 2 + rows: 3 + Label { + text: qsTr("Text") + } + LineEdit { + backendValue: backendValues.%2_text + Layout.fillWidth: true + } + + Label { + text: qsTr("Wrap mode") + } + + ComboBox { + Layout.fillWidth: true + backendValue: backendValues.%2_wrapMode + scope: "Text" + model: ["NoWrap", "WordWrap", "WrapAnywhere", "WrapAtWordBoundaryOrAnywhere"] + } + + Label { + text: qsTr("Elide") + } + + ComboBox { + Layout.fillWidth: true + backendValue: backendValues.%2_elide + scope: "Text" + model: ["ElideNone", "ElideLeft", "ElideMiddle", "ElideRight"] + } + + Label { + text: qsTr("Alignment") + } + + AligmentHorizontalButtons { + backendValue: backendValues.%2_horizontalAlignment; + + } + + Label { + text: ("") + } + + AligmentVerticalButtons { + backendValue: backendValues.%2_verticalAlignment; + } + + + Label { + text: qsTr("Format") + } + ComboBox { + scope: "Text" + model: ["PlainText", "RichText", "AutoText"] + backendValue: backendValues.%2_textFormat + Layout.fillWidth: true + } + + Label { + text: qsTr("Render type") + toolTip: qsTr("Override the default rendering type for this item.") + } + ComboBox { + scope: "Text" + model: ["QtRendering", "NativeRendering"] + backendValue: backendValues.%2_renderType + Layout.fillWidth: true + } + + Label { + text: qsTr("Font size mode") + toolTip: qsTr("Specifies how the font size of the displayed text is determined.") + } + ComboBox { + scope: "Text" + model: ["FixedSize", "HorizontalFit", "VerticalFit", "Fit"] + backendValue: backendValues.%2_fontSizeMode + Layout.fillWidth: true + } + + + Label { + text: qsTr("Line height") + tooltip: qsTr("Sets the line height for the text.") + } + + SpinBox { + Layout.fillWidth: true + backendValue: (backendValues.%2_lineHeight === undefined) ? dummyBackendValue : backendValues.lineHeight + maximumValue: 500 + minimumValue: 0 + decimals: 2 + stepSize: 0.1 + } + + } +} diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/PropertyTemplates/UrlEditorTemplate.template b/share/qtcreator/qmldesigner/propertyEditorQmlSources/PropertyTemplates/UrlEditorTemplate.template index 4d3a015e7b..361bedccfb 100644 --- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/PropertyTemplates/UrlEditorTemplate.template +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/PropertyTemplates/UrlEditorTemplate.template @@ -2,8 +2,7 @@ Label { text: "%1" tooltip: "%1" } -LineEdit { - backendValue: backendValues.%2 +UrlChooser { Layout.fillWidth: true - showTranslateCheckBox: false + backendValue: backendValues.%2 }
\ No newline at end of file diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick/LayoutPoperties.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick/LayoutPoperties.qml index 8ae5dcdb91..cbe22a8a3d 100644 --- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick/LayoutPoperties.qml +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick/LayoutPoperties.qml @@ -27,6 +27,7 @@ import QtQuick 2.0 import HelperWidgets 2.0 import QtQuick.Layouts 1.0 import QtQuick.Controls 1.0 as Controls +import StudioControls 1.0 as StudioControls SectionLayout { property bool isInModel: backendValue.isInModel; @@ -40,7 +41,7 @@ SectionLayout { onBackendValueChanged: evaluateAlignment() onValueFromBackendChanged: evaluateAlignment() - property int spinBoxWidth: 62 + property int spinBoxWidth: 82 Connections { target: modelNodeBackend @@ -129,40 +130,43 @@ SectionLayout { SecondColumnLayout { - Controls.ComboBox { + StudioControls.ComboBox { ColorLogic { id: colorLogic } + Layout.fillWidth: true - ExtendedFunctionButton { - x: 2 - anchors.verticalCenter: parent.verticalCenter + ExtendedFunctionLogic { + id: extFuncLogic backendValue: backendValues.Layout_alignment - visible: horizontalAlignmentComboBox.enabled onReseted: { horizontalAlignmentComboBox.currentIndex = 0 verticalAlignmentComboBox.currentIndex = 0 } } + actionIndicator.icon.color: extFuncLogic.color + actionIndicator.icon.text: extFuncLogic.glyph + actionIndicator.onClicked: extFuncLogic.show() + + actionIndicator.visible: true + + labelColor: horizontalAlignmentComboBox.currentIndex === 0 ? colorLogic.__defaultTextColor : colorLogic.__changedTextColor + id: horizontalAlignmentComboBox property bool __isCompleted: false - property color textColor: currentIndex === 0 ? colorLogic.__defaultTextColor : colorLogic.__changedTextColor model: ["AlignLeft", "AlignHCenter", "AlignRight"] - onCurrentIndexChanged: { + onActivated: { if (!horizontalAlignmentComboBox.__isCompleted) return; + horizontalAlignmentComboBox.currentIndex = index composeExpressionString(); } - style: CustomComboBoxStyle { - textColor: horizontalAlignmentComboBox.textColor - } - Component.onCompleted: { horizontalAlignmentComboBox.__isCompleted = true; } @@ -181,36 +185,30 @@ SectionLayout { SecondColumnLayout { - Controls.ComboBox { + StudioControls.ComboBox { id: verticalAlignmentComboBox + Layout.fillWidth: true - ExtendedFunctionButton { - x: 2 - anchors.verticalCenter: parent.verticalCenter - backendValue: backendValues.Layout_alignment - visible: verticalAlignmentComboBox.enabled - onReseted: { - horizontalAlignmentComboBox.currentIndex = 0 - verticalAlignmentComboBox.currentIndex = 0 - } - } + actionIndicator.icon.color: extFuncLogic.color + actionIndicator.icon.text: extFuncLogic.glyph + actionIndicator.onClicked: extFuncLogic.show() + + actionIndicator.visible: true + + labelColor: verticalAlignmentComboBox.currentIndex === 0 ? colorLogic.__defaultTextColor : colorLogic.__changedTextColor property bool __isCompleted: false - property color textColor: currentIndex === 0 ? colorLogic.__defaultTextColor : colorLogic.__changedTextColor model: ["AlignVCenter", "AlignTop","AlignBottom","AlignBaseline"] - onCurrentIndexChanged: { + onActivated: { if (!verticalAlignmentComboBox.__isCompleted) return; + verticalAlignmentComboBox.currentIndex = index composeExpressionString(); } - style: CustomComboBoxStyle { - textColor: verticalAlignmentComboBox.textColor - } - Component.onCompleted: { verticalAlignmentComboBox.__isCompleted = true; } diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick/ListViewSpecifics.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick/ListViewSpecifics.qml index a4314dc267..9baa1d4ba1 100644 --- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick/ListViewSpecifics.qml +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick/ListViewSpecifics.qml @@ -100,6 +100,7 @@ Column { model: ["LeftToRight", "RightToLeft"] backendValue: backendValues.layoutDirection scope: "Qt" + Layout.fillWidth: true } ExpandingSpacer { @@ -117,6 +118,7 @@ Column { model: ["NoSnap", "SnapToItem", "SnapOneItem"] backendValue: backendValues.snapMode scope: "ListView" + Layout.fillWidth: true } ExpandingSpacer { diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/ColorButton.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/ColorButton.qml index 5449f85eb6..d190b0e8e4 100644 --- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/ColorButton.qml +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/ColorButton.qml @@ -40,18 +40,14 @@ Item { property int sliderMargins: 6 - onHueChanged: { - //hueSlider.value = hue; - invalidateColor(); - } + property bool block: false signal clicked onAlphaChanged: invalidateColor(); - onSaturationChanged: invalidateColor(); - onLightnessChanged: invalidateColor(); + onHueChanged: invalidateColor(); onColorChanged: { var myAlpha = color.a @@ -60,8 +56,6 @@ Item { colorButton.alpha = myAlpha } - property bool block: false - function invalidateColor() { if (block) return; @@ -145,14 +139,12 @@ Item { onPaint: { var ctx = hubeBox.getContext('2d') - ctx.save() - ctx.clearRect(0, 0, hubeBox.width, hubeBox.height); for (var row = 0; row < hubeBox.height; row++){ var gradient = ctx.createLinearGradient(0, 0, hubeBox.width,0); - var l = Math.abs(row - hubeBox.height) / hubeBox.height + var l = Math.abs(row - hubeBox.height) / hubeBox.height gradient.addColorStop(0, Qt.hsla(hubeBox.hue, 0, l, 1)); gradient.addColorStop(1, Qt.hsla(hubeBox.hue, 1, l, 1)); @@ -160,20 +152,15 @@ Item { ctx.fillStyle = gradient; ctx.fillRect(0, row, hubeBox.width, 1); } - ctx.restore() - } - } Canvas { id: canvas opacity: 0.8 - anchors.fill: parent - antialiasing: true property real cavnasSaturation: colorButton.saturation @@ -197,7 +184,6 @@ Item { ctx.strokeStyle = canvas.strokeStyle ctx.lineWidth = 1 - ctx.beginPath() ctx.moveTo(0, yy) ctx.lineTo(canvas.width, yy) @@ -210,7 +196,6 @@ Item { ctx.restore() } - } MouseArea { @@ -221,12 +206,11 @@ Item { var xx = Math.max(0, Math.min(mouse.x, parent.width)) var yy = Math.max(0, Math.min(mouse.y, parent.height)) - colorButton.lightness = 1.0 - yy / parent.height; - colorButton.saturation = xx / parent.width; + colorButton.lightness = 1.0 - yy / parent.height; + colorButton.saturation = xx / parent.width; } } onPressed: positionChanged(mouse) - onReleased: colorButton.clicked() } Rectangle { @@ -238,7 +222,6 @@ Item { } } - HueSlider { id: hueSlider anchors.left: surround.right @@ -250,7 +233,6 @@ Item { colorButton.hue = value } onClicked: colorButton.clicked() - } Row { @@ -259,9 +241,7 @@ Item { spacing: 10 Column { - spacing: 10 - Row { z: 3 spacing: 1 @@ -281,9 +261,10 @@ Item { maximumValue: 255 decimals: 0 - onCompressedValueModified: { - if (color.r !== value && !colorButton.block) { - color.r = (value / 255.0) + onValueModified: { + var tmp = redSlider.value / 255.0 + if (colorButton.color.r !== tmp && !colorButton.block) { + colorButton.color.r = tmp colorButton.clicked() } } @@ -300,7 +281,6 @@ Item { elide: Text.ElideRight anchors.verticalCenter: parent.verticalCenter } - DoubleSpinBox { id: greenSlider width: 64 @@ -310,9 +290,10 @@ Item { maximumValue: 255 decimals: 0 - onCompressedValueModified: { - if (color.g !== value && !colorButton.block) { - color.g = (value / 255.0) + onValueModified: { + var tmp = greenSlider.value / 255.0 + if (colorButton.color.g !== tmp && !colorButton.block) { + colorButton.color.g = tmp colorButton.clicked() } } @@ -338,9 +319,10 @@ Item { maximumValue: 255 decimals: 0 - onCompressedValueModified: { - if (color.b !== value && !colorButton.block) { - color.b = (value / 255.0) + onValueModified: { + var tmp = blueSlider.value / 255.0 + if (colorButton.color.b !== tmp && !colorButton.block) { + colorButton.color.b = tmp colorButton.clicked() } } @@ -357,13 +339,12 @@ Item { elide: Text.ElideRight anchors.verticalCenter: parent.verticalCenter } - DoubleSpinBox { id: alphaSlider width: 64 - onCompressedValueModified: { - if (colorButton.alpha !== value && !colorButton.block) { - colorButton.alpha = value + onValueModified: { + if (colorButton.alpha !== alphaSlider.value && !colorButton.block) { + colorButton.alpha = alphaSlider.value colorButton.clicked() } } @@ -372,7 +353,6 @@ Item { } Column { - spacing: 10 Row { z: 3 @@ -387,9 +367,9 @@ Item { DoubleSpinBox { id: hueSlider2 width: 64 - onCompressedValueModified: { - if (colorButton.hue !== value && !colorButton.block) { - colorButton.hue = value + onValueModified: { + if (colorButton.hue !== hueSlider2.value && !colorButton.block) { + colorButton.hue = hueSlider2.value colorButton.clicked() } } @@ -406,13 +386,12 @@ Item { elide: Text.ElideRight anchors.verticalCenter: parent.verticalCenter } - DoubleSpinBox { id: saturationSlider width: 64 - onCompressedValueModified: { - if (colorButton.saturation !== value && !colorButton.block) { - colorButton.saturation = value + onValueModified: { + if (colorButton.saturation !== saturationSlider.value && !colorButton.block) { + colorButton.saturation = saturationSlider.value colorButton.clicked() } } @@ -432,9 +411,9 @@ Item { DoubleSpinBox { id: lightnessSlider width: 64 - onCompressedValueModified: { - if (colorButton.lightness !== value && !colorButton.block) { - colorButton.lightness = value + onValueModified: { + if (colorButton.lightness !== lightnessSlider.value && !colorButton.block) { + colorButton.lightness = lightnessSlider.value colorButton.clicked() } } diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/DoubleSpinBox.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/DoubleSpinBox.qml index 5b368565ae..fbe5031b40 100644 --- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/DoubleSpinBox.qml +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/DoubleSpinBox.qml @@ -33,61 +33,32 @@ Item { property alias decimals: spinBox.decimals property alias hasSlider: spinBox.hasSlider - property real minimumValue: 0.0 - property real maximumValue: 1.0 - property real stepSize: 0.1 + property alias value: spinBox.realValue - property alias sliderIndicatorVisible: spinBox.sliderIndicatorVisible - - property real value + property alias minimumValue: spinBox.realFrom + property alias maximumValue: spinBox.realTo + property alias stepSize: spinBox.realStepSize - onValueChanged: spinBox.value = wrapper.value * spinBox.factor + property alias sliderIndicatorVisible: spinBox.sliderIndicatorVisible - signal compressedValueModified signal valueModified width: 90 implicitHeight: spinBox.height - onStepSizeChanged: spinBox.convert("stepSize", wrapper.stepSize) - onMinimumValueChanged: spinBox.convert("from", wrapper.minimumValue) - onMaximumValueChanged: spinBox.convert("to", wrapper.maximumValue) - - StudioControls.SpinBox { + StudioControls.RealSpinBox { id: spinBox - onValueModified: wrapper.valueModified() - onCompressedValueModified: wrapper.compressedValueModified() - - onValueChanged: { - if (spinBox.__initialized) - wrapper.value = spinBox.value / spinBox.factor - } + property bool hasSlider: spinBox.sliderIndicatorVisible width: wrapper.width - decimals: 2 - actionIndicatorVisible: false - property bool __initialized: false - - property bool hasSlider: spinBox.sliderIndicatorVisible - - Component.onCompleted: { - spinBox.__initialized = true - - spinBox.convert("stepSize", wrapper.stepSize) - spinBox.convert("from", wrapper.minimumValue) - spinBox.convert("to", wrapper.maximumValue) - - spinBox.value = wrapper.value * spinBox.factor - } - - function convert(target, value) { - if (!spinBox.__initialized) - return - spinBox[target] = Math.round(value * spinBox.factor) - } + realFrom: 0.0 + realTo: 1.0 + realStepSize: 0.1 + decimals: 2 + onRealValueModified: wrapper.valueModified() } } diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/FlickableSection.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/FlickableSection.qml index 50590efc1f..5d39863a64 100644 --- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/FlickableSection.qml +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/FlickableSection.qml @@ -34,7 +34,7 @@ Section { id: root - property int spinBoxWidth: 62 + property int spinBoxWidth: 96 SectionLayout { @@ -71,7 +71,7 @@ Section { Label { text: qsTr("Movement") - tooltip: qsTr("Determines whether the flickable will give a feeling that the edges of the view are soft, rather than a hard physical boundary.") + tooltip: qsTr("Determines whether the Flickable will give a feeling that the edges of the view are soft, rather than a hard physical boundary.") } SecondColumnLayout { diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/FontSection.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/FontSection.qml index 28621e4be6..0360012570 100644 --- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/FontSection.qml +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/FontSection.qml @@ -35,16 +35,24 @@ Section { anchors.right: parent.right caption: qsTr("Font") + property string fontName: "font" + property bool showStyle: false - property variant fontFamily: backendValues.font_family - property variant pointSize: backendValues.font_pointSize - property variant pixelSize: backendValues.font_pixelSize + function getBackendValue(name) + { + print(fontSection.fontName + "_" + name) + return backendValues[fontSection.fontName + "_" + name] + } + + property variant fontFamily: getBackendValue("family") + property variant pointSize: getBackendValue("pointSize") + property variant pixelSize: getBackendValue("pixelSize") - property variant boldStyle: backendValues.font_bold - property variant italicStyle: backendValues.font_italic - property variant underlineStyle: backendValues.font_underline - property variant strikeoutStyle: backendValues.font_strikeout + property variant boldStyle: getBackendValue("bold") + property variant italicStyle: getBackendValue("italic") + property variant underlineStyle: getBackendValue("underline") + property variant strikeoutStyle: getBackendValue("strikeout") onPointSizeChanged: { sizeWidget.setPointPixelSize(); @@ -140,6 +148,10 @@ Section { } FontStyleButtons { + bold: fontSection.boldStyle + italic: fontSection.italicStyle + underline: fontSection.underlineStyle + strikeout: fontSection.strikeoutStyle } Label { @@ -149,7 +161,7 @@ Section { ComboBox { Layout.fillWidth: true - backendValue: backendValues.font_capitalization + backendValue: getBackendValue("capitalization") model: ["MixedCase", "AllUppercase", "AllLowercase", "SmallCaps", "Capitalize"] scope: "Font" } @@ -161,7 +173,7 @@ Section { ComboBox { Layout.fillWidth: true - backendValue: backendValues.font_weight + backendValue: getBackendValue("weight") model: ["Normal", "Light", "ExtraLight", "Thin", "Medium", "DemiBold", "Bold", "ExtraBold", "Black"] scope: "Font" } @@ -193,7 +205,7 @@ Section { maximumValue: 500 minimumValue: -500 decimals: 2 - backendValue: backendValues.font_wordSpacing + backendValue: getBackendValue("wordSpacing") Layout.fillWidth: true Layout.minimumWidth: 60 stepSize: 0.1 @@ -212,7 +224,7 @@ Section { maximumValue: 500 minimumValue: -500 decimals: 2 - backendValue: backendValues.font_letterSpacing + backendValue: getBackendValue("letterSpacing") Layout.fillWidth: true Layout.minimumWidth: 60 stepSize: 0.1 @@ -230,7 +242,7 @@ Section { CheckBox { text: qsTr("Kerning") Layout.fillWidth: true - backendValue: (backendValues.font_kerning === undefined) ? dummyBackendValue : backendValues.font_kerning + backendValue: getBackendValue("kerning") tooltip: qsTr("Enables or disables the kerning OpenType feature when shaping the text. Disabling this may " + "improve performance when creating or changing the text, at the expense of some cosmetic features. The default value is true.") } @@ -238,7 +250,7 @@ Section { CheckBox { text: qsTr("Prefer shaping") Layout.fillWidth: true - backendValue: (backendValues.font_preferShaping === undefined) ? dummyBackendValue : backendValues.font_preferShaping + backendValue: getBackendValue("preferShaping") tooltip: qsTr("Sometimes, a font will apply complex rules to a set of characters in order to display them correctly.\n" + "In some writing systems, such as Brahmic scripts, this is required in order for the text to be legible, whereas in " + "Latin script,\n it is merely a cosmetic feature. Setting the preferShaping property to false will disable all such features\nwhen they are not required, which will improve performance in most cases.") diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/SpinBox.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/SpinBox.qml index 02665fc77a..2ec1052877 100644 --- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/SpinBox.qml +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/SpinBox.qml @@ -34,9 +34,9 @@ Item { property alias decimals: spinBox.decimals property alias hasSlider: spinBox.hasSlider - property real minimumValue: 0.0 - property real maximumValue: 99 - property real stepSize: 1.0 + property alias minimumValue: spinBox.realFrom + property alias maximumValue: spinBox.realTo + property alias stepSize: spinBox.realStepSize property alias backendValue: spinBox.backendValue property alias sliderIndicatorVisible: spinBox.sliderIndicatorVisible @@ -44,35 +44,15 @@ Item { width: 96 implicitHeight: spinBox.height - property bool __initialized: false - - Component.onCompleted: { - wrapper.__initialized = true - - convert("stepSize", stepSize) - convert("from", minimumValue) - convert("to", maximumValue) - } - - onStepSizeChanged: convert("stepSize", stepSize) - onMinimumValueChanged: convert("from", minimumValue) - onMaximumValueChanged: convert("to", maximumValue) - - function convert(target, value) { - if (!wrapper.__initialized) - return - spinBox[target] = Math.round(value * spinBox.factor) - } - - StudioControls.SpinBox { + StudioControls.RealSpinBox { id: spinBox - property real realValue: value / factor + onDragStarted: hideCursor(); + onDragEnded: restoreCursor(); + property variant backendValue property bool hasSlider: wrapper.sliderIndicatorVisible - from: minimumValue * factor - to: maximumValue * factor width: wrapper.width ExtendedFunctionLogic { @@ -88,13 +68,14 @@ Item { id: colorLogic backendValue: spinBox.backendValue onValueFromBackendChanged: { - spinBox.value = valueFromBackend * spinBox.factor; + if (valueFromBackend !== undefined) + spinBox.realValue = valueFromBackend } } labelColor: edit ? StudioTheme.Values.themeTextColor : colorLogic.textColor - onCompressedValueModified: { + onCompressedRealValueModified: { if (backendValue.value !== realValue) backendValue.value = realValue; } diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/CheckBox.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/CheckBox.qml index 142421ee99..5ec29bbe2e 100644 --- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/CheckBox.qml +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/CheckBox.qml @@ -65,6 +65,7 @@ T.CheckBox { text: myCheckBox.text font: myCheckBox.font color: StudioTheme.Values.themeTextColor + visible: text !== "" } ActionIndicator { @@ -90,9 +91,9 @@ T.CheckBox { border.width: StudioTheme.Values.border T.Label { - id: checkBoxIcon - x: (parent.width - width) / 2 - y: (parent.height - height) / 2 + id: checkedIcon + x: (parent.width - checkedIcon.width) / 2 + y: (parent.height - checkedIcon.height) / 2 text: StudioTheme.Constants.tickIcon visible: myCheckBox.checkState === Qt.Checked color: StudioTheme.Values.themeTextColor @@ -100,17 +101,16 @@ T.CheckBox { font.family: StudioTheme.Constants.iconFont.family } - /* - // Tristate only - Rectangle { - x: (parent.width - width) / 2 - y: (parent.height - height) / 2 - width: 16 - height: 3 - color: myCheckBox.palette.text + T.Label { + id: partiallyCheckedIcon + x: (parent.width - checkedIcon.width) / 2 + y: (parent.height - checkedIcon.height) / 2 + text: StudioTheme.Constants.triState visible: myCheckBox.checkState === Qt.PartiallyChecked + color: StudioTheme.Values.themeTextColor + font.pixelSize: StudioTheme.Values.sliderControlSizeMulti + font.family: StudioTheme.Constants.iconFont.family } -*/ } states: [ @@ -150,7 +150,11 @@ T.CheckBox { border.color: StudioTheme.Values.themeControlOutlineDisabled } PropertyChanges { - target: checkBoxIcon + target: checkedIcon + color: StudioTheme.Values.themeTextColorDisabled + } + PropertyChanges { + target: partiallyCheckedIcon color: StudioTheme.Values.themeTextColorDisabled } PropertyChanges { diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/ComboBox.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/ComboBox.qml index c61e7e0dbf..2f2ebb0541 100644 --- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/ComboBox.qml +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/ComboBox.qml @@ -53,7 +53,7 @@ T.ComboBox { wheelEnabled: false onFocusChanged: { - if (!focus) + if (!myComboBox.focus) comboBoxPopup.close() } diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/RealSliderPopup.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/RealSliderPopup.qml new file mode 100644 index 0000000000..d260940c39 --- /dev/null +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/RealSliderPopup.qml @@ -0,0 +1,91 @@ +/**************************************************************************** +** +** Copyright (C) 2019 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +****************************************************************************/ + +import QtQuick 2.12 +import QtQuick.Templates 2.12 as T +import StudioTheme 1.0 as StudioTheme + +T.Popup { + id: sliderPopup + + property T.Control myControl + + dim: false + closePolicy: T.Popup.CloseOnEscape | T.Popup.CloseOnPressOutsideParent + + background: Rectangle { + color: StudioTheme.Values.themeControlBackground + border.color: StudioTheme.Values.themeInteraction + } + + contentItem: T.Slider { + id: slider + anchors.fill: parent + + bottomPadding: 0 + topPadding: 0 + rightPadding: 3 + leftPadding: 3 + + from: myControl.realFrom + value: myControl.realValue + to: myControl.realTo + + focusPolicy: Qt.NoFocus + + handle: Rectangle { + x: slider.leftPadding + slider.visualPosition * (slider.availableWidth - width) + y: slider.topPadding + (slider.availableHeight / 2) - (height / 2) + width: StudioTheme.Values.sliderHandleWidth + height: StudioTheme.Values.sliderHandleHeight + radius: 0 + color: slider.pressed ? StudioTheme.Values.themeInteraction : StudioTheme.Values.themeControlOutline + } + + background: Rectangle { + x: slider.leftPadding + y: slider.topPadding + (slider.availableHeight / 2) - (height / 2) + width: slider.availableWidth + height: StudioTheme.Values.sliderTrackHeight + radius: 0 + color: StudioTheme.Values.themeSliderInactiveTrack + + Rectangle { + width: slider.visualPosition * parent.width + height: parent.height + color: StudioTheme.Values.themeSliderActiveTrack + radius: 0 + } + } + + onMoved: { + var currValue = myControl.value + myControl.realValue = slider.value + + if (currValue !== myControl.realValue) + myControl.realValueModified() + } + } +} diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/RealSpinBox.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/RealSpinBox.qml new file mode 100644 index 0000000000..68ad7f6aa6 --- /dev/null +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/RealSpinBox.qml @@ -0,0 +1,346 @@ +/**************************************************************************** +** +** Copyright (C) 2019 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +****************************************************************************/ + +import QtQuick 2.12 +import QtQuick.Templates 2.12 as T +import StudioTheme 1.0 as StudioTheme + +T.SpinBox { + id: mySpinBox + + property real realFrom: 0.0 + property real realTo: 99.0 + property real realValue: 1.0 + property real realStepSize: 1.0 + + property alias labelColor: spinBoxInput.color + property alias actionIndicator: actionIndicator + + property int decimals: 0 + + property real minStepSize: 1 + property real maxStepSize: 10 + + property bool edit: spinBoxInput.activeFocus + property bool hover: false // This property is used to indicate the global hover state + property bool drag: false + + property alias actionIndicatorVisible: actionIndicator.visible + property real __actionIndicatorWidth: StudioTheme.Values.squareComponentWidth + property real __actionIndicatorHeight: StudioTheme.Values.height + + property bool spinBoxIndicatorVisible: true + property real __spinBoxIndicatorWidth: StudioTheme.Values.smallRectWidth - 2 + * StudioTheme.Values.border + property real __spinBoxIndicatorHeight: StudioTheme.Values.height / 2 + - StudioTheme.Values.border + + property alias sliderIndicatorVisible: sliderIndicator.visible + property real __sliderIndicatorWidth: StudioTheme.Values.squareComponentWidth + property real __sliderIndicatorHeight: StudioTheme.Values.height + + signal realValueModified + signal compressedRealValueModified + signal dragStarted + signal dragEnded + + // Use custom wheel handling due to bugs + property bool __wheelEnabled: false + wheelEnabled: false + + width: StudioTheme.Values.squareComponentWidth * 5 + height: StudioTheme.Values.height + + leftPadding: spinBoxIndicatorDown.x + spinBoxIndicatorDown.width + - (spinBoxIndicatorVisible ? 0 : StudioTheme.Values.border) + rightPadding: sliderIndicator.width - (sliderIndicatorVisible ? StudioTheme.Values.border : 0) + + font.pixelSize: StudioTheme.Values.myFontSize + editable: true + + // Leave this in for now + from: -99 + value: 0 + to: 99 + + validator: DoubleValidator { + id: doubleValidator + locale: mySpinBox.locale.name + notation: DoubleValidator.StandardNotation + decimals: mySpinBox.decimals + bottom: Math.min(mySpinBox.realFrom, mySpinBox.realTo) + top: Math.max(mySpinBox.realFrom, mySpinBox.realTo) + } + + ActionIndicator { + id: actionIndicator + myControl: mySpinBox + x: 0 + y: 0 + width: actionIndicator.visible ? __actionIndicatorWidth : 0 + height: actionIndicator.visible ? __actionIndicatorHeight : 0 + } + + up.indicator: RealSpinBoxIndicator { + id: spinBoxIndicatorUp + myControl: mySpinBox + iconFlip: -1 + visible: spinBoxIndicatorVisible + onRealReleased: mySpinBox.realIncrease() + onRealPressAndHold: mySpinBox.realIncrease() + x: actionIndicator.width + (actionIndicatorVisible ? 0 : StudioTheme.Values.border) + y: StudioTheme.Values.border + width: spinBoxIndicatorVisible ? __spinBoxIndicatorWidth : 0 + height: spinBoxIndicatorVisible ? __spinBoxIndicatorHeight : 0 + + realEnabled: (mySpinBox.realFrom < mySpinBox.realTo) ? (mySpinBox.realValue < mySpinBox.realTo) : (mySpinBox.realValue > mySpinBox.realTo) + } + + down.indicator: RealSpinBoxIndicator { + id: spinBoxIndicatorDown + myControl: mySpinBox + visible: spinBoxIndicatorVisible + onRealReleased: mySpinBox.realDecrease() + onRealPressAndHold: mySpinBox.realDecrease() + x: actionIndicator.width + (actionIndicatorVisible ? 0 : StudioTheme.Values.border) + y: spinBoxIndicatorUp.y + spinBoxIndicatorUp.height + width: spinBoxIndicatorVisible ? __spinBoxIndicatorWidth : 0 + height: spinBoxIndicatorVisible ? __spinBoxIndicatorHeight : 0 + + realEnabled: (mySpinBox.realFrom < mySpinBox.realTo) ? (mySpinBox.realValue > mySpinBox.realFrom) : (mySpinBox.realValue < mySpinBox.realFrom) + } + + contentItem: RealSpinBoxInput { + id: spinBoxInput + myControl: mySpinBox + validator: doubleValidator + } + + background: Rectangle { + id: spinBoxBackground + color: StudioTheme.Values.themeControlOutline + border.color: StudioTheme.Values.themeControlOutline + border.width: StudioTheme.Values.border + width: mySpinBox.width + height: mySpinBox.height + } + + CheckIndicator { + id: sliderIndicator + myControl: mySpinBox + myPopup: sliderPopup + x: spinBoxInput.x + spinBoxInput.width - StudioTheme.Values.border + width: sliderIndicator.visible ? __sliderIndicatorWidth : 0 + height: sliderIndicator.visible ? __sliderIndicatorHeight : 0 + visible: false // reasonable default + } + + RealSliderPopup { + id: sliderPopup + myControl: mySpinBox + x: spinBoxInput.x + y: StudioTheme.Values.height - StudioTheme.Values.border + width: spinBoxInput.width + sliderIndicator.width - StudioTheme.Values.border + height: StudioTheme.Values.sliderHeight + + enter: Transition { + } + exit: Transition { + } + } + + textFromValue: function (value, locale) { + return Number(mySpinBox.realValue).toLocaleString(locale, 'f', mySpinBox.decimals) + } + + valueFromText: function (text, locale) { + mySpinBox.setRealValue(Number.fromLocaleString(locale, spinBoxInput.text)) + return 0 + } + + states: [ + State { + name: "default" + when: mySpinBox.enabled && !mySpinBox.hover + && !mySpinBox.edit && !mySpinBox.drag + PropertyChanges { + target: mySpinBox + __wheelEnabled: false + } + PropertyChanges { + target: spinBoxInput + selectByMouse: false + } + PropertyChanges { + target: spinBoxBackground + color: StudioTheme.Values.themeControlOutline + border.color: StudioTheme.Values.themeControlOutline + } + }, + State { + name: "edit" + when: mySpinBox.edit + PropertyChanges { + target: mySpinBox + __wheelEnabled: true + } + PropertyChanges { + target: spinBoxInput + selectByMouse: true + } + PropertyChanges { + target: spinBoxBackground + color: StudioTheme.Values.themeInteraction + border.color: StudioTheme.Values.themeInteraction + } + }, + State { + name: "drag" + when: mySpinBox.drag + PropertyChanges { + target: spinBoxBackground + color: StudioTheme.Values.themeInteraction + border.color: StudioTheme.Values.themeInteraction + } + }, + State { + name: "disabled" + when: !mySpinBox.enabled + PropertyChanges { + target: spinBoxBackground + color: StudioTheme.Values.themeControlOutlineDisabled + border.color: StudioTheme.Values.themeControlOutlineDisabled + } + } + ] + + Timer { + id: myTimer + repeat: false + running: false + interval: 200 + onTriggered: mySpinBox.compressedRealValueModified() + } + + onRealValueChanged: { + spinBoxInput.text = mySpinBox.textFromValue(mySpinBox.realValue, mySpinBox.locale) + mySpinBox.value = 0 // Without setting value back to 0, it can occur that one of + // the indicator will be disabled due to range logic. + } + onRealValueModified: myTimer.restart() + + onFocusChanged: mySpinBox.setValueFromInput() + onDisplayTextChanged: spinBoxInput.text = mySpinBox.displayText + onActiveFocusChanged: { + if (mySpinBox.activeFocus) + // QTBUG-75862 && mySpinBox.focusReason === Qt.TabFocusReason) + spinBoxInput.selectAll() + + if (sliderPopup.opened && !mySpinBox.activeFocus) + sliderPopup.close() + } + + Keys.onPressed: { + if (event.key === Qt.Key_Up || event.key === Qt.Key_Down) { + event.accepted = true + + // Store current step size + var currStepSize = mySpinBox.realStepSize + + // Set stepSize according to used modifier key + if (event.modifiers & Qt.ControlModifier) + mySpinBox.realStepSize = mySpinBox.minStepSize + + if (event.modifiers & Qt.ShiftModifier) + mySpinBox.realStepSize = mySpinBox.maxStepSize + + if (event.key === Qt.Key_Up) + mySpinBox.realIncrease() + else + mySpinBox.realDecrease() + + // Reset step size + mySpinBox.realStepSize = currStepSize + } + + if (event.key === Qt.Key_Escape) + mySpinBox.focus = false + + // FIX: This is a temporary fix for QTBUG-74239 + if (event.key === Qt.Key_Return || event.key === Qt.Key_Enter) + mySpinBox.setValueFromInput() + } + + function clamp(v, lo, hi) { + return (v < lo || v > hi) ? Math.min(Math.max(lo, v), hi) : v + } + + function setValueFromInput() { + // FIX: This is a temporary fix for QTBUG-74239 + var currValue = mySpinBox.realValue + + // Call the function but don't use return value. The realValue property + // will be implicitly set inside the function/procedure. + mySpinBox.valueFromText(spinBoxInput.text, mySpinBox.locale) + + if (mySpinBox.realValue !== currValue) { + mySpinBox.realValueModified() + } else { + // Check if input text differs in format from the current value + var tmpInputValue = mySpinBox.textFromValue(mySpinBox.realValue, mySpinBox.locale) + + if (tmpInputValue !== spinBoxInput.text) + spinBoxInput.text = tmpInputValue + } + } + + function setRealValue(value) { + mySpinBox.realValue = clamp(value, + mySpinBox.validator.bottom, + mySpinBox.validator.top) + } + + function realDecrease() { + // Store the current value for comparison + var currValue = mySpinBox.realValue + mySpinBox.valueFromText(spinBoxInput.text, mySpinBox.locale) + + setRealValue(mySpinBox.realValue - realStepSize) + + if (mySpinBox.realValue !== currValue) + mySpinBox.realValueModified() + } + + function realIncrease() { + // Store the current value for comparison + var currValue = mySpinBox.realValue + mySpinBox.valueFromText(spinBoxInput.text, mySpinBox.locale) + + setRealValue(mySpinBox.realValue + realStepSize) + + if (mySpinBox.realValue !== currValue) + mySpinBox.realValueModified() + } +} diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/RealSpinBoxIndicator.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/RealSpinBoxIndicator.qml new file mode 100644 index 0000000000..3ff6b3b3e0 --- /dev/null +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/RealSpinBoxIndicator.qml @@ -0,0 +1,196 @@ +/**************************************************************************** +** +** Copyright (C) 2019 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +****************************************************************************/ + +import QtQuick 2.12 +import QtQuick.Templates 2.12 as T +import StudioTheme 1.0 as StudioTheme + +Rectangle { + id: spinBoxIndicator + + property T.Control myControl + + property bool hover: false + property bool pressed: false + property bool released: false + property bool realEnabled: true + + signal realPressed + signal realPressAndHold + signal realReleased + + property alias iconFlip: spinBoxIndicatorIconScale.yScale + + color: StudioTheme.Values.themeControlBackground + border.width: 0 + + onEnabledChanged: invalidateEnabled() + onRealEnabledChanged: { + invalidateEnabled() + if (spinBoxIndicator.realEnabled === false) + pressAndHoldTimer.stop() + } + + // This function is meant to synchronize enabled with realEnable to avoid + // the internal logic messing with the actual state. + function invalidateEnabled() { + spinBoxIndicator.enabled = spinBoxIndicator.realEnabled + } + + Timer { + id: pressAndHoldTimer + repeat: true + running: false + interval: 100 + onTriggered: spinBoxIndicator.realPressAndHold() + } + + // This MouseArea is a workaround to avoid some hover state related bugs + // when using the actual signal 'up.hovered'. QTBUG-74688 + MouseArea { + id: spinBoxIndicatorMouseArea + + property bool pressedAndHeld: false + + anchors.fill: parent + // Shift the MouseArea down by 1 pixel due to potentially overlapping areas + anchors.topMargin: iconFlip < 0 ? 0 : 1 + anchors.bottomMargin: iconFlip < 0 ? 1 : 0 + hoverEnabled: true + pressAndHoldInterval: 500 + onContainsMouseChanged: spinBoxIndicator.hover = containsMouse + onContainsPressChanged: spinBoxIndicator.pressed = containsPress + onPressed: { + myControl.forceActiveFocus() + spinBoxIndicator.realPressed() + mouse.accepted = true + } + onPressAndHold: { + pressAndHoldTimer.restart() + pressedAndHeld = true + } + onReleased: { + // Only trigger real released when pressAndHold isn't active + if (!pressAndHoldTimer.running && containsMouse) + spinBoxIndicator.realReleased() + pressAndHoldTimer.stop() + mouse.accepted = true + pressedAndHeld = false + } + onEntered: { + if (pressedAndHeld) + pressAndHoldTimer.restart() + } + onExited: { + if (pressAndHoldTimer.running) + pressAndHoldTimer.stop() + } + } + + T.Label { + id: spinBoxIndicatorIcon + text: StudioTheme.Constants.upDownSquare2 + color: StudioTheme.Values.themeTextColor + renderType: Text.NativeRendering + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + font.pixelSize: StudioTheme.Values.spinControlIconSizeMulti + font.family: StudioTheme.Constants.iconFont.family + anchors.fill: parent + transform: Scale { + id: spinBoxIndicatorIconScale + origin.x: 0 + origin.y: spinBoxIndicatorIcon.height / 2 + yScale: 1 + } + + states: [ + State { + name: "default" + when: myControl.enabled && spinBoxIndicator.enabled + PropertyChanges { + target: spinBoxIndicatorIcon + color: StudioTheme.Values.themeTextColor + } + }, + State { + name: "disabled" + when: !myControl.enabled || !spinBoxIndicator.enabled + PropertyChanges { + target: spinBoxIndicatorIcon + color: StudioTheme.Values.themeTextColorDisabled + } + } + ] + } + + states: [ + State { + name: "default" + when: myControl.enabled && !(spinBoxIndicator.hover + || myControl.hover) + && !spinBoxIndicator.pressed && !myControl.edit + && !myControl.drag + PropertyChanges { + target: spinBoxIndicator + color: StudioTheme.Values.themeControlBackground + } + }, + State { + name: "hovered" + when: (spinBoxIndicator.hover || myControl.hover) + && !spinBoxIndicator.pressed && !myControl.edit + && !myControl.drag + PropertyChanges { + target: spinBoxIndicator + color: StudioTheme.Values.themeHoverHighlight + } + }, + State { + name: "pressed" + when: spinBoxIndicator.pressed + PropertyChanges { + target: spinBoxIndicator + color: StudioTheme.Values.themeInteraction + } + }, + State { + name: "edit" + when: myControl.edit + PropertyChanges { + target: spinBoxIndicator + color: StudioTheme.Values.themeFocusEdit + } + }, + State { + name: "drag" + when: myControl.drag + PropertyChanges { + target: spinBoxIndicator + color: StudioTheme.Values.themeFocusDrag + } + } + ] +} diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/RealSpinBoxInput.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/RealSpinBoxInput.qml new file mode 100644 index 0000000000..91f4d667e1 --- /dev/null +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/RealSpinBoxInput.qml @@ -0,0 +1,211 @@ +/**************************************************************************** +** +** Copyright (C) 2019 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +****************************************************************************/ + +import QtQuick 2.12 +import QtQuick.Templates 2.12 as T +import StudioTheme 1.0 as StudioTheme + +TextInput { + id: textInput + + property T.Control myControl + + property bool edit: textInput.activeFocus + property bool drag: false + + z: 2 + font: myControl.font + color: StudioTheme.Values.themeTextColor + selectionColor: StudioTheme.Values.themeTextSelectionColor + selectedTextColor: StudioTheme.Values.themeTextSelectedTextColor + + horizontalAlignment: Qt.AlignRight + verticalAlignment: Qt.AlignVCenter + leftPadding: StudioTheme.Values.inputHorizontalPadding + rightPadding: StudioTheme.Values.inputHorizontalPadding + + readOnly: !myControl.editable + validator: myControl.validator + inputMethodHints: myControl.inputMethodHints + selectByMouse: false + activeFocusOnPress: false + clip: true + + // TextInput focus needs to be set to activeFocus whenever it changes, + // otherwise TextInput will get activeFocus whenever the parent SpinBox gets + // activeFocus. This will lead to weird side effects. + onActiveFocusChanged: textInput.focus = activeFocus + + Rectangle { + id: textInputArea + color: StudioTheme.Values.themeControlBackground + border.color: StudioTheme.Values.themeControlOutline + border.width: StudioTheme.Values.border + x: 0 + y: 0 + z: -1 + width: textInput.width + height: StudioTheme.Values.height + } + + DragHandler { + id: dragHandler + target: null + acceptedDevices: PointerDevice.Mouse + enabled: true + + property real initialValue: 0 + + onActiveChanged: { + if (dragHandler.active) { + dragHandler.initialValue = myControl.realValue + mouseArea.cursorShape = Qt.ClosedHandCursor + myControl.drag = true + myControl.dragStarted() + } else { + mouseArea.cursorShape = Qt.PointingHandCursor + myControl.drag = false + myControl.dragEnded() + } + } + onTranslationChanged: { + var currValue = myControl.realValue + myControl.setRealValue(dragHandler.initialValue + (translation.x * myControl.realStepSize)) + if (currValue !== myControl.realValue) + myControl.realValueModified() + } + } + + TapHandler { + id: tapHandler + acceptedDevices: PointerDevice.Mouse + enabled: true + onTapped: { + textInput.forceActiveFocus() + textInput.deselect() // QTBUG-75862 + } + } + + MouseArea { + id: mouseArea + anchors.fill: parent + enabled: true + hoverEnabled: true + propagateComposedEvents: true + acceptedButtons: Qt.LeftButton + cursorShape: Qt.PointingHandCursor + // Sets the global hover + onContainsMouseChanged: myControl.hover = containsMouse + onPressed: mouse.accepted = false + onWheel: { + if (!myControl.__wheelEnabled) + return + + var currValue = myControl.realValue + myControl.valueFromText(textInput.text, myControl.locale) + myControl.setRealValue(myControl.realValue + (wheel.angleDelta.y / 120.0 * myControl.realStepSize)) + + if (currValue !== myControl.realValue) + myControl.realValueModified() + } + } + + states: [ + State { + name: "default" + when: myControl.enabled && !textInput.edit + && !mouseArea.containsMouse && !myControl.drag + PropertyChanges { + target: textInputArea + color: StudioTheme.Values.themeControlBackground + border.color: StudioTheme.Values.themeControlOutline + } + PropertyChanges { + target: dragHandler + enabled: true + } + PropertyChanges { + target: tapHandler + enabled: true + } + PropertyChanges { + target: mouseArea + cursorShape: Qt.PointingHandCursor + } + }, + State { + name: "hovered" + when: myControl.hover && !textInput.edit && !myControl.drag + PropertyChanges { + target: textInputArea + color: StudioTheme.Values.themeHoverHighlight + border.color: StudioTheme.Values.themeControlOutline + } + }, + State { + name: "edit" + when: textInput.edit + PropertyChanges { + target: textInputArea + color: StudioTheme.Values.themeFocusEdit + border.color: StudioTheme.Values.themeInteraction + } + PropertyChanges { + target: dragHandler + enabled: false + } + PropertyChanges { + target: tapHandler + enabled: false + } + PropertyChanges { + target: mouseArea + cursorShape: Qt.IBeamCursor + } + }, + State { + name: "drag" + when: myControl.drag + PropertyChanges { + target: textInputArea + color: StudioTheme.Values.themeFocusDrag + border.color: StudioTheme.Values.themeInteraction + } + }, + State { + name: "disabled" + when: !myControl.enabled + PropertyChanges { + target: textInputArea + color: StudioTheme.Values.themeControlBackgroundDisabled + border.color: StudioTheme.Values.themeControlOutlineDisabled + } + PropertyChanges { + target: textInput + color: StudioTheme.Values.themeTextColorDisabled + } + } + ] +} diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/ScrollView.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/ScrollView.qml index bf1b3937b9..3f21c4dbbf 100644 --- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/ScrollView.qml +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/ScrollView.qml @@ -43,10 +43,10 @@ T.ScrollView { ScrollBar.vertical: ScrollBar { id: verticalScrollBar parent: control - x: control.width - width - StudioTheme.Values.border + x: control.width - verticalScrollBar.width - StudioTheme.Values.border y: StudioTheme.Values.border - height: control.availableHeight - 2 * StudioTheme.Values.border - - (bothVisible ? horizontalThickness : 0) + height: control.availableHeight - (2 * StudioTheme.Values.border) + - (control.bothVisible ? control.horizontalThickness : 0) active: control.ScrollBar.horizontal.active } @@ -54,9 +54,9 @@ T.ScrollView { id: horizontalScrollBar parent: control x: StudioTheme.Values.border - y: control.height - height - StudioTheme.Values.border - width: control.availableWidth - 2 * StudioTheme.Values.border - - (bothVisible ? verticalThickness : 0) + y: control.height - horizontalScrollBar.height - StudioTheme.Values.border + width: control.availableWidth - (2 * StudioTheme.Values.border) + - (control.bothVisible ? control.verticalThickness : 0) active: control.ScrollBar.vertical.active } } diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/Slider.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/Slider.qml index 7e111b6851..e8cfe2a13a 100644 --- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/Slider.qml +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/Slider.qml @@ -77,8 +77,8 @@ T.Slider { handle: Rectangle { id: sliderHandle x: slider.leftPadding + (slider.visualPosition * slider.availableWidth) - - sliderHandle.width / 2 - y: slider.topPadding + slider.availableHeight / 2 - sliderHandle.height / 2 + - (sliderHandle.width / 2) + y: slider.topPadding + (slider.availableHeight / 2) - (sliderHandle.height / 2) z: 20 implicitWidth: StudioTheme.Values.sliderHandleWidth implicitHeight: StudioTheme.Values.sliderHandleHeight diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/SliderPopup.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/SliderPopup.qml index beb6da4a8f..a80ff78c40 100644 --- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/SliderPopup.qml +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/SliderPopup.qml @@ -57,7 +57,7 @@ T.Popup { handle: Rectangle { x: slider.leftPadding + slider.visualPosition * (slider.availableWidth - width) - y: slider.topPadding + slider.availableHeight / 2 - height / 2 + y: slider.topPadding + (slider.availableHeight / 2) - (height / 2) width: StudioTheme.Values.sliderHandleWidth height: StudioTheme.Values.sliderHandleHeight radius: 0 @@ -66,7 +66,7 @@ T.Popup { background: Rectangle { x: slider.leftPadding - y: slider.topPadding + slider.availableHeight / 2 - height / 2 + y: slider.topPadding + (slider.availableHeight / 2) - (height / 2) width: slider.availableWidth height: StudioTheme.Values.sliderTrackHeight radius: 0 @@ -81,7 +81,20 @@ T.Popup { } onMoved: { - myControl.value = value + var currValue = myControl.value + myControl.value = slider.value + + if (currValue !== myControl.value) + myControl.valueModified() + } + } + + onOpened: { + // Check if value is in sync with text input, if not sync it! + var val = myControl.valueFromText(myControl.contentItem.text, + myControl.locale) + if (myControl.value !== val) { + myControl.value = val myControl.valueModified() } } diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/SpinBox.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/SpinBox.qml index e10a334bd6..c60e7002f2 100644 --- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/SpinBox.qml +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/SpinBox.qml @@ -36,7 +36,6 @@ T.SpinBox { property int decimals: 0 property int factor: Math.pow(10, decimals) - property real defaultStepSize: 1 property real minStepSize: 1 property real maxStepSize: 10 @@ -49,9 +48,9 @@ T.SpinBox { property real __actionIndicatorHeight: StudioTheme.Values.height property bool spinBoxIndicatorVisible: true - property real __spinBoxIndicatorWidth: StudioTheme.Values.smallRectWidth - 2 - * StudioTheme.Values.border - property real __spinBoxIndicatorHeight: StudioTheme.Values.height / 2 + property real __spinBoxIndicatorWidth: StudioTheme.Values.smallRectWidth - (2 + * StudioTheme.Values.border) + property real __spinBoxIndicatorHeight: (StudioTheme.Values.height / 2) - StudioTheme.Values.border property alias sliderIndicatorVisible: sliderIndicator.visible @@ -80,8 +79,8 @@ T.SpinBox { locale: mySpinBox.locale.name notation: DoubleValidator.StandardNotation decimals: mySpinBox.decimals - bottom: Math.min(mySpinBox.from, mySpinBox.to) / factor - top: Math.max(mySpinBox.from, mySpinBox.to) / factor + bottom: Math.min(mySpinBox.from, mySpinBox.to) / mySpinBox.factor + top: Math.max(mySpinBox.from, mySpinBox.to) / mySpinBox.factor } IntValidator { @@ -110,10 +109,12 @@ T.SpinBox { pressed: mySpinBox.up.pressed iconFlip: -1 - x: actionIndicator.width + (actionIndicator.visible ? 0 : StudioTheme.Values.border) + x: actionIndicator.width + (actionIndicatorVisible ? 0 : StudioTheme.Values.border) y: StudioTheme.Values.border width: spinBoxIndicatorVisible ? __spinBoxIndicatorWidth : 0 height: spinBoxIndicatorVisible ? __spinBoxIndicatorHeight : 0 + + enabled: (mySpinBox.from < mySpinBox.to) ? mySpinBox.value < mySpinBox.to : mySpinBox.value > mySpinBox.to } down.indicator: SpinBoxIndicator { @@ -128,6 +129,8 @@ T.SpinBox { y: spinBoxIndicatorUp.y + spinBoxIndicatorUp.height width: spinBoxIndicatorVisible ? __spinBoxIndicatorWidth : 0 height: spinBoxIndicatorVisible ? __spinBoxIndicatorHeight : 0 + + enabled: (mySpinBox.from < mySpinBox.to) ? mySpinBox.value > mySpinBox.from : mySpinBox.value < mySpinBox.from } contentItem: SpinBoxInput { @@ -171,12 +174,12 @@ T.SpinBox { } textFromValue: function (value, locale) { - return Number(value / factor).toLocaleString(locale, 'f', - mySpinBox.decimals) + return Number(value / mySpinBox.factor).toLocaleString(locale, 'f', + mySpinBox.decimals) } valueFromText: function (text, locale) { - return Number.fromLocaleString(locale, text) * factor + return Number.fromLocaleString(locale, text) * mySpinBox.factor } states: [ @@ -235,38 +238,6 @@ T.SpinBox { } ] - onActiveFocusChanged: { - if (mySpinBox.activeFocus) - // QTBUG-75862 && mySpinBox.focusReason === Qt.TabFocusReason) - spinBoxInput.selectAll() - - if (sliderPopup.opened && !mySpinBox.activeFocus) - sliderPopup.close() - } - - onFocusChanged: { - // FIX: This is a temporary fix for QTBUG-74239 - var currValue = mySpinBox.value - - if (!spinBoxInput.acceptableInput) - mySpinBox.value = clamp(valueFromText(spinBoxInput.text, - mySpinBox.locale), - mySpinBox.validator.bottom * factor, - mySpinBox.validator.top * factor) - else - mySpinBox.value = valueFromText(spinBoxInput.text, mySpinBox.locale) - - if (spinBoxInput.text !== mySpinBox.displayText) - spinBoxInput.text = mySpinBox.displayText - - if (mySpinBox.value !== currValue) - mySpinBox.valueModified() - } - - onDisplayTextChanged: { - spinBoxInput.text = mySpinBox.displayText - } - Timer { id: myTimer repeat: false @@ -276,57 +247,56 @@ T.SpinBox { } onValueModified: myTimer.restart() + onFocusChanged: mySpinBox.setValueFromInput() + onDisplayTextChanged: spinBoxInput.text = mySpinBox.displayText + onActiveFocusChanged: { + if (mySpinBox.activeFocus) + // QTBUG-75862 && mySpinBox.focusReason === Qt.TabFocusReason) + spinBoxInput.selectAll() + + if (sliderPopup.opened && !mySpinBox.activeFocus) + sliderPopup.close() + } Keys.onPressed: { if (event.key === Qt.Key_Up || event.key === Qt.Key_Down) { event.accepted = true - mySpinBox.stepSize = defaultStepSize + // Store current step size + var currStepSize = mySpinBox.stepSize if (event.modifiers & Qt.ControlModifier) - mySpinBox.stepSize = minStepSize + mySpinBox.stepSize = mySpinBox.minStepSize if (event.modifiers & Qt.ShiftModifier) - mySpinBox.stepSize = maxStepSize + mySpinBox.stepSize = mySpinBox.maxStepSize + // Check if value is in sync with text input, if not sync it! var val = mySpinBox.valueFromText(spinBoxInput.text, mySpinBox.locale) if (mySpinBox.value !== val) mySpinBox.value = val - var curValue = mySpinBox.value + var currValue = mySpinBox.value if (event.key === Qt.Key_Up) mySpinBox.increase() else mySpinBox.decrease() - if (curValue !== mySpinBox.value) + if (currValue !== mySpinBox.value) mySpinBox.valueModified() + + // Reset step size + mySpinBox.stepSize = currStepSize } if (event.key === Qt.Key_Escape) mySpinBox.focus = false // FIX: This is a temporary fix for QTBUG-74239 - if (event.key === Qt.Key_Return || event.key === Qt.Key_Enter) { - var currValue = mySpinBox.value - - if (!spinBoxInput.spinBoxInput) - mySpinBox.value = clamp(valueFromText(spinBoxInput.text, - mySpinBox.locale), - mySpinBox.validator.bottom * factor, - mySpinBox.validator.top * factor) - else - mySpinBox.value = valueFromText(spinBoxInput.text, - mySpinBox.locale) - - if (spinBoxInput.text !== mySpinBox.displayText) - spinBoxInput.text = mySpinBox.displayText - - if (mySpinBox.value !== currValue) - mySpinBox.valueModified() - } + if (event.key === Qt.Key_Return || event.key === Qt.Key_Enter) + mySpinBox.setValueFromInput() } function clamp(v, lo, hi) { @@ -335,4 +305,24 @@ T.SpinBox { return v } + + function setValueFromInput() { + // FIX: This is a temporary fix for QTBUG-74239 + var currValue = mySpinBox.value + + if (!spinBoxInput.acceptableInput) + mySpinBox.value = clamp(valueFromText(spinBoxInput.text, + mySpinBox.locale), + mySpinBox.validator.bottom * mySpinBox.factor, + mySpinBox.validator.top * mySpinBox.factor) + else + mySpinBox.value = valueFromText(spinBoxInput.text, + mySpinBox.locale) + + if (spinBoxInput.text !== mySpinBox.displayText) + spinBoxInput.text = mySpinBox.displayText + + if (mySpinBox.value !== currValue) + mySpinBox.valueModified() + } } diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/SpinBoxIndicator.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/SpinBoxIndicator.qml index f75b8b47fd..3f272860e9 100644 --- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/SpinBoxIndicator.qml +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/SpinBoxIndicator.qml @@ -77,7 +77,7 @@ Rectangle { when: myControl.enabled && !(spinBoxIndicator.hover || myControl.hover) && !spinBoxIndicator.pressed && !myControl.edit - && !myControl.drag + && !myControl.drag && spinBoxIndicator.enabled PropertyChanges { target: spinBoxIndicator color: StudioTheme.Values.themeControlBackground @@ -87,7 +87,7 @@ Rectangle { name: "hovered" when: (spinBoxIndicator.hover || myControl.hover) && !spinBoxIndicator.pressed && !myControl.edit - && !myControl.drag + && !myControl.drag && spinBoxIndicator.enabled PropertyChanges { target: spinBoxIndicator color: StudioTheme.Values.themeHoverHighlight @@ -95,7 +95,7 @@ Rectangle { }, State { name: "pressed" - when: spinBoxIndicator.pressed + when: spinBoxIndicator.pressed && spinBoxIndicator.enabled PropertyChanges { target: spinBoxIndicator color: StudioTheme.Values.themeInteraction @@ -103,7 +103,7 @@ Rectangle { }, State { name: "edit" - when: myControl.edit + when: myControl.edit && spinBoxIndicator.enabled PropertyChanges { target: spinBoxIndicator color: StudioTheme.Values.themeFocusEdit @@ -111,7 +111,7 @@ Rectangle { }, State { name: "drag" - when: myControl.drag + when: myControl.drag && spinBoxIndicator.enabled PropertyChanges { target: spinBoxIndicator color: StudioTheme.Values.themeFocusDrag @@ -119,7 +119,7 @@ Rectangle { }, State { name: "disabled" - when: !myControl.enabled + when: !myControl.enabled || !spinBoxIndicator.enabled PropertyChanges { target: spinBoxIndicator color: StudioTheme.Values.themeControlBackgroundDisabled diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/SpinBoxInput.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/SpinBoxInput.qml index e2f718176e..50b4a068aa 100644 --- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/SpinBoxInput.qml +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/SpinBoxInput.qml @@ -91,10 +91,10 @@ TextInput { } } onTranslationChanged: { - var curValue = myControl.value + var currValue = myControl.value myControl.value = initialValue + translation.x - if (curValue !== myControl.value) + if (currValue !== myControl.value) myControl.valueModified() } } @@ -128,10 +128,10 @@ TextInput { if (myControl.value !== val) myControl.value = val - var curValue = myControl.value + var currValue = myControl.value myControl.value += wheel.angleDelta.y / 120 - if (curValue !== myControl.value) + if (currValue !== myControl.value) myControl.valueModified() } } diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/TextArea.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/TextArea.qml index 7432d00bb0..6aaa71c7e8 100644 --- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/TextArea.qml +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/TextArea.qml @@ -38,9 +38,9 @@ TextField { T.Popup { id: popup - x: relativePopupX + x: myTextField.relativePopupX y: myTextField.height - StudioTheme.Values.border - width: popupWidth + width: myTextField.popupWidth height: scrollView.height background: Rectangle { color: StudioTheme.Values.themeFocusEdit @@ -128,12 +128,8 @@ TextField { } Keys.onPressed: { - if (event.key === Qt.Key_Escape) { - if (popup.opened) - popup.close() - else - myTextField.focus = false - } + if (event.key === Qt.Key_Escape) + popup.opened ? popup.close() : myTextField.focus = false if ((event.key === Qt.Key_Return || event.key === Qt.Key_Enter) && !popup.opened) { diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/qmldir b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/qmldir index 02acf99dff..ee876cc935 100644 --- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/qmldir +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/qmldir @@ -13,6 +13,10 @@ ItemDelegate 1.0 ItemDelegate.qml Menu 1.0 Menu.qml MenuItem 1.0 MenuItem.qml MenuSeparator 1.0 MenuSeparator.qml +RealSliderPopup 1.0 RealSliderPopup.qml +RealSpinBox 1.0 RealSpinBox.qml +RealSpinBoxIndicator 1.0 RealSpinBoxIndicator.qml +RealSpinBoxInput 1.0 RealSpinBoxInput.qml ScrollBar 1.0 ScrollBar.qml ScrollView 1.0 ScrollView.qml SecondColumnLayout 1.0 SecondColumnLayout.qml diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioTheme/Values.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioTheme/Values.qml index 2055572e44..d02d75446c 100644 --- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioTheme/Values.qml +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioTheme/Values.qml @@ -33,7 +33,7 @@ QtObject { property real baseFont: 12 property real baseIconFont: 10 - property real scaleFactor: 1 + property real scaleFactor: 1.1 property real height: Math.round(values.baseHeight * values.scaleFactor) property real myFontSize: Math.round(values.baseFont * values.scaleFactor) @@ -47,10 +47,10 @@ QtObject { property real sliderHeight: values.height / 2 * 1.5 // TODO:Have a look at -> sliderAreaHeight: Data.Values.height/2*1.5 property real sliderControlSize: 12 - property real sliderControlSizeMulti: sliderControlSize * scaleFactor + property real sliderControlSizeMulti: values.sliderControlSize * values.scaleFactor property real spinControlIconSize: 8 - property real spinControlIconSizeMulti: spinControlIconSize * scaleFactor + property real spinControlIconSizeMulti: values.spinControlIconSize * values.scaleFactor property real sliderTrackHeight: values.height / 4 property real sliderHandleHeight: values.sliderTrackHeight * 2 @@ -62,18 +62,18 @@ QtObject { property real sliderPointerWidth: Math.round(7 * values.scaleFactor) property real sliderPointerHeight: Math.round(2 * values.scaleFactor) - property real checkBoxSpacing: 6 // TODO Does look strange with scale factor applied + property real checkBoxSpacing: Math.round(6 * values.scaleFactor) property real columnWidth: 225 + (175 * (values.scaleFactor * 2)) property real marginTopBottom: 4 property real border: 1 - property real maxComboBoxPopupHeight: 300 - property real maxTextAreaPopupHeight: 150 + property real maxComboBoxPopupHeight: Math.round(300 * values.scaleFactor) + property real maxTextAreaPopupHeight: Math.round(150 * values.scaleFactor) - property real contextMenuLabelSpacing: 30 - property real contextMenuHorizontalPadding: 6 + property real contextMenuLabelSpacing: Math.round(30 * values.scaleFactor) + property real contextMenuHorizontalPadding: Math.round(6 * values.scaleFactor) property real inputHorizontalPadding: Math.round(4 * values.scaleFactor) @@ -87,7 +87,7 @@ QtObject { property string themePanelBackground: "#2a2a2a" property string themeHoverHighlight: "#313131" property string themeColumnBackground: "#363636" - property string themeFocusEdit: "#606060" + property string themeFocusEdit: "#444444" property string themeFocusDrag: "#565656" property string themeControlBackgroundPressed: "#606060" diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioTheme/qmldir b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioTheme/qmldir index b768fe63a2..b768fe63a2 100644..100755 --- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioTheme/qmldir +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioTheme/qmldir diff --git a/share/qtcreator/templates/wizards/projects/plaincpp/wizard.json b/share/qtcreator/templates/wizards/projects/plaincpp/wizard.json index af7e84362d..f5fbffaa84 100644 --- a/share/qtcreator/templates/wizards/projects/plaincpp/wizard.json +++ b/share/qtcreator/templates/wizards/projects/plaincpp/wizard.json @@ -49,7 +49,7 @@ { "trKey": "CMake", "value": "cmake", - "condition": "%{JS: value('Plugins).indexOf('CMakeProjectManager') >= 0}" + "condition": "%{JS: value('Plugins').indexOf('CMakeProjectManager') >= 0}" }, { "trKey": "Qbs", diff --git a/src/libs/clangsupport/CMakeLists.txt b/src/libs/clangsupport/CMakeLists.txt index 84cdbaf8b9..0366d74f8c 100644 --- a/src/libs/clangsupport/CMakeLists.txt +++ b/src/libs/clangsupport/CMakeLists.txt @@ -11,7 +11,6 @@ add_qtc_library(ClangSupport annotationsmessage.cpp annotationsmessage.h baseserverproxy.cpp baseserverproxy.h cancelmessage.cpp cancelmessage.h - changedfilepathcompressor.h clangcodemodelclientinterface.cpp clangcodemodelclientinterface.h clangcodemodelclientmessages.h clangcodemodelclientproxy.cpp clangcodemodelclientproxy.h @@ -36,6 +35,8 @@ add_qtc_library(ClangSupport connectionclient.cpp connectionclient.h connectionserver.cpp connectionserver.h diagnosticcontainer.cpp diagnosticcontainer.h + directoryandfilepathid.h + directorypathid.h documentschangedmessage.cpp documentschangedmessage.h documentsclosedmessage.cpp documentsclosedmessage.h documentsopenedmessage.cpp documentsopenedmessage.h @@ -61,6 +62,10 @@ add_qtc_library(ClangSupport filepathstoragesources.h filepathstoragesqlitestatementfactory.h filepathview.h + filestatus.h + filestatuscache.cpp filestatuscache.h + filesystem.cpp filesystem.h + filesysteminterface.h fixitcontainer.cpp fixitcontainer.h followsymbolmessage.cpp followsymbolmessage.h generatedfiles.cpp generatedfiles.h diff --git a/src/libs/clangsupport/clangpathwatcher.h b/src/libs/clangsupport/clangpathwatcher.h index 7a7d6ccfcf..5ce02458c4 100644 --- a/src/libs/clangsupport/clangpathwatcher.h +++ b/src/libs/clangsupport/clangpathwatcher.h @@ -1,4 +1,4 @@ -; /**************************************************************************** +/**************************************************************************** ** ** Copyright (C) 2016 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ @@ -57,7 +57,7 @@ void set_greedy_intersection_call( class WatcherEntry { public: - ProjectPartId id; + ProjectChunkId id; DirectoryPathId directoryPathId; FilePathId filePathId; long long lastModified = -1; @@ -98,9 +98,9 @@ public: ClangPathWatcher(FilePathCachingInterface &pathCache, FileSystemInterface &fileSystem, ClangPathWatcherNotifier *notifier = nullptr) - : m_pathCache(pathCache) - , m_fileStatusCache(fileSystem) + : m_fileStatusCache(fileSystem) , m_fileSystem(fileSystem) + , m_pathCache(pathCache) , m_notifier(notifier) { QObject::connect(&m_fileSystemWatcher, @@ -140,25 +140,6 @@ public: m_notifier = notifier; } - static std::vector<uint> idsFromIdPaths(const std::vector<IdPaths> &idPaths) - { - std::vector<uint> ids; - ids.reserve(idPaths.size()); - - auto extractId = [] (const IdPaths &idPath) { - return idPath.id; - }; - - std::transform(idPaths.begin(), - idPaths.end(), - std::back_inserter(ids), - extractId); - - std::sort(ids.begin(), ids.end()); - - return ids; - } - std::size_t sizeOfIdPaths(const std::vector<IdPaths> &idPaths) { auto sumSize = [] (std::size_t size, const IdPaths &idPath) { @@ -168,19 +149,19 @@ public: return std::accumulate(idPaths.begin(), idPaths.end(), std::size_t(0), sumSize); } - std::pair<WatcherEntries, ProjectPartIds> convertIdPathsToWatcherEntriesAndIds( + std::pair<WatcherEntries, ProjectChunkIds> convertIdPathsToWatcherEntriesAndIds( const std::vector<IdPaths> &idPaths) { WatcherEntries entries; entries.reserve(sizeOfIdPaths(idPaths)); - ProjectPartIds ids; + ProjectChunkIds ids; ids.reserve(ids.size()); auto outputIterator = std::back_inserter(entries); for (const IdPaths &idPath : idPaths) { - ProjectPartId id = idPath.id; + ProjectChunkId id = idPath.id; ids.push_back(id); @@ -214,7 +195,7 @@ public: m_fileSystemWatcher.addPaths(convertWatcherEntriesToDirectoryPathList(filteredPaths)); } - void removeUnusedEntries(const WatcherEntries &entries, const ProjectPartIds &ids) + void removeUnusedEntries(const WatcherEntries &entries, const ProjectChunkIds &ids) { auto oldEntries = notAnymoreWatchedEntriesWithIds(entries, ids); @@ -294,7 +275,7 @@ public: } WatcherEntries notAnymoreWatchedEntriesWithIds(const WatcherEntries &newEntries, - const ProjectPartIds &ids) const + const ProjectChunkIds &ids) const { auto oldEntries = notAnymoreWatchedEntries(newEntries, std::less<WatcherEntry>()); @@ -420,25 +401,22 @@ public: return filePathIds; } - ProjectPartIds idsForWatcherEntries(const WatcherEntries &foundEntries) + std::vector<IdPaths> idPathsForWatcherEntries(WatcherEntries &&foundEntries) { - ProjectPartIds ids; - ids.reserve(foundEntries.size()); - - std::transform(foundEntries.begin(), - foundEntries.end(), - std::back_inserter(ids), - [&](WatcherEntry entry) { return entry.id; }); + std::sort(foundEntries.begin(), foundEntries.end(), [](WatcherEntry first, WatcherEntry second) { + return std::tie(first.id, first.filePathId) < std::tie(second.id, second.filePathId); + }); - return ids; - } + std::vector<IdPaths> idPaths; + idPaths.reserve(foundEntries.size()); - ProjectPartIds uniqueIds(ProjectPartIds &&ids) - { - std::sort(ids.begin(), ids.end()); - ids.erase(std::unique(ids.begin(), ids.end()), ids.end()); + for (WatcherEntry entry : foundEntries) { + if (idPaths.empty() || idPaths.back().id != entry.id) + idPaths.push_back({entry.id, {}}); + idPaths.back().filePathIds.push_back(entry.filePathId); + } - return std::move(ids); + return idPaths; } void addChangedPathForFilePath(DirectoryPathIds &&directoryPathIds) @@ -446,10 +424,12 @@ public: if (m_notifier) { WatcherEntries foundEntries = watchedEntriesForPaths(std::move(directoryPathIds)); - ProjectPartIds changedIds = idsForWatcherEntries(foundEntries); + FilePathIds watchedFilePathIds = watchedPaths(foundEntries); + + std::vector<IdPaths> changedIdPaths = idPathsForWatcherEntries(std::move(foundEntries)); - m_notifier->pathsWithIdsChanged(uniqueIds(std::move(changedIds))); - m_notifier->pathsChanged(watchedPaths(foundEntries)); + m_notifier->pathsChanged(watchedFilePathIds); + m_notifier->pathsWithIdsChanged(changedIdPaths); } } diff --git a/src/libs/clangsupport/clangpathwatchernotifier.h b/src/libs/clangsupport/clangpathwatchernotifier.h index 393525dbf2..248925ffb9 100644 --- a/src/libs/clangsupport/clangpathwatchernotifier.h +++ b/src/libs/clangsupport/clangpathwatchernotifier.h @@ -26,9 +26,8 @@ #pragma once #include "clangsupport_global.h" - -#include <filepathid.h> -#include <projectpartid.h> +#include "filepathid.h" +#include "idpaths.h" #include <utils/smallstringvector.h> @@ -41,7 +40,7 @@ public: ClangPathWatcherNotifier(const ClangPathWatcherNotifier &) = delete; ClangPathWatcherNotifier &operator=(const ClangPathWatcherNotifier &) = delete; - virtual void pathsWithIdsChanged(const ProjectPartIds &ids) = 0; + virtual void pathsWithIdsChanged(const std::vector<IdPaths> &idPaths) = 0; virtual void pathsChanged(const FilePathIds &filePathIds) = 0; protected: diff --git a/src/libs/clangsupport/clangrefactoringclientmessages.h b/src/libs/clangsupport/clangrefactoringclientmessages.h index 012ca0431d..87b61b4c6b 100644 --- a/src/libs/clangsupport/clangrefactoringclientmessages.h +++ b/src/libs/clangsupport/clangrefactoringclientmessages.h @@ -27,6 +27,5 @@ #include "alivemessage.h" #include "progressmessage.h" -#include "sourcelocationsforrenamingmessage.h" #include "sourcerangesanddiagnosticsforquerymessage.h" #include "sourcerangesforquerymessage.h" diff --git a/src/libs/clangsupport/clangrefactoringservermessages.h b/src/libs/clangsupport/clangrefactoringservermessages.h index dd1cb3a6d7..8a79518c7e 100644 --- a/src/libs/clangsupport/clangrefactoringservermessages.h +++ b/src/libs/clangsupport/clangrefactoringservermessages.h @@ -27,7 +27,6 @@ #include "cancelmessage.h" #include "endmessage.h" -#include "requestsourcelocationforrenamingmessage.h" #include "requestsourcerangesanddiagnosticsforquerymessage.h" #include "requestsourcerangesforquerymessage.h" #include "removegeneratedfilesmessage.h" diff --git a/src/libs/clangsupport/clangsupport-lib.pri b/src/libs/clangsupport/clangsupport-lib.pri index dc66408e58..18896c0ea0 100644 --- a/src/libs/clangsupport/clangsupport-lib.pri +++ b/src/libs/clangsupport/clangsupport-lib.pri @@ -56,14 +56,12 @@ SOURCES += \ $$PWD/requestannotationsmessage.cpp \ $$PWD/requestfollowsymbolmessage.cpp \ $$PWD/requestreferencesmessage.cpp \ - $$PWD/requestsourcelocationforrenamingmessage.cpp \ $$PWD/requestsourcerangesanddiagnosticsforquerymessage.cpp \ $$PWD/requestsourcerangesforquerymessage.cpp \ $$PWD/requesttooltipmessage.cpp \ $$PWD/sourcelocationcontainer.cpp \ $$PWD/sourcelocationcontainerv2.cpp \ $$PWD/sourcelocationscontainer.cpp \ - $$PWD/sourcelocationsforrenamingmessage.cpp \ $$PWD/sourcerangecontainer.cpp \ $$PWD/processcreator.cpp \ $$PWD/processexception.cpp \ @@ -163,14 +161,12 @@ HEADERS += \ $$PWD/requestannotationsmessage.h \ $$PWD/requestfollowsymbolmessage.h \ $$PWD/requestreferencesmessage.h \ - $$PWD/requestsourcelocationforrenamingmessage.h \ $$PWD/requestsourcerangesanddiagnosticsforquerymessage.h \ $$PWD/requestsourcerangesforquerymessage.h \ $$PWD/requesttooltipmessage.h \ $$PWD/sourcelocationcontainer.h \ $$PWD/sourcelocationcontainerv2.h \ $$PWD/sourcelocationscontainer.h \ - $$PWD/sourcelocationsforrenamingmessage.h \ $$PWD/sourcerangecontainer.h \ $$PWD/filepath.h \ $$PWD/processcreator.h \ diff --git a/src/libs/clangsupport/idpaths.h b/src/libs/clangsupport/idpaths.h index d67a73e83e..d0945f7ff5 100644 --- a/src/libs/clangsupport/idpaths.h +++ b/src/libs/clangsupport/idpaths.h @@ -25,21 +25,60 @@ #pragma once -#include "projectpartid.h" #include "filepathid.h" +#include "projectpartid.h" +#include "sourceentry.h" namespace ClangBackEnd { -class IdPaths +class ProjectChunkId { public: ProjectPartId id; + SourceType sourceType; + + friend bool operator==(ProjectChunkId first, ProjectChunkId second) + { + return first.id == second.id && first.sourceType == second.sourceType; + } + + friend bool operator==(ProjectChunkId first, ProjectPartId second) + { + return first.id == second; + } + + friend bool operator==(ProjectPartId first, ProjectChunkId second) + { + return first == second.id; + } + + friend bool operator!=(ProjectChunkId first, ProjectChunkId second) + { + return !(first == second); + } + + friend bool operator<(ProjectChunkId first, ProjectChunkId second) + { + return std::tie(first.id, first.sourceType) < std::tie(second.id, second.sourceType); + } + + friend bool operator<(ProjectChunkId first, ProjectPartId second) { return first.id < second; } + + friend bool operator<(ProjectPartId first, ProjectChunkId second) { return first < second.id; } +}; + +class IdPaths +{ +public: + ProjectChunkId id; FilePathIds filePathIds; - friend bool operator==(const IdPaths &first, const IdPaths &second) + friend bool operator==(IdPaths first, IdPaths second) { return first.id == second.id && first.filePathIds == second.filePathIds; } }; +using ProjectChunkIds = std::vector<ProjectChunkId>; + } // namespace ClangBackEnd diff --git a/src/libs/clangsupport/precompiledheadersupdatedmessage.h b/src/libs/clangsupport/precompiledheadersupdatedmessage.h index 5bd24dcd49..9e3e3b981c 100644 --- a/src/libs/clangsupport/precompiledheadersupdatedmessage.h +++ b/src/libs/clangsupport/precompiledheadersupdatedmessage.h @@ -26,6 +26,7 @@ #pragma once #include "clangsupport_global.h" +#include "filepathid.h" #include "projectpartid.h" #include <utils/smallstringio.h> @@ -37,6 +38,7 @@ class PrecompiledHeadersUpdatedMessage public: PrecompiledHeadersUpdatedMessage() = default; PrecompiledHeadersUpdatedMessage(ProjectPartId projectPartId) + { projectPartIds.push_back(projectPartId); } diff --git a/src/libs/clangsupport/refactoringclientinterface.cpp b/src/libs/clangsupport/refactoringclientinterface.cpp index 5e3b98df66..e862e4e4d9 100644 --- a/src/libs/clangsupport/refactoringclientinterface.cpp +++ b/src/libs/clangsupport/refactoringclientinterface.cpp @@ -38,9 +38,6 @@ void RefactoringClientInterface::dispatch(const MessageEnvelop &messageEnvelop) case MessageType::AliveMessage: alive(); break; - case MessageType::SourceLocationsForRenamingMessage: - sourceLocationsForRenamingMessage(messageEnvelop.message<SourceLocationsForRenamingMessage>()); - break; case MessageType::SourceRangesAndDiagnosticsForQueryMessage: sourceRangesAndDiagnosticsForQueryMessage(messageEnvelop.message<SourceRangesAndDiagnosticsForQueryMessage>()); break; diff --git a/src/libs/clangsupport/refactoringclientinterface.h b/src/libs/clangsupport/refactoringclientinterface.h index c1127592d6..c7d2fcf7d0 100644 --- a/src/libs/clangsupport/refactoringclientinterface.h +++ b/src/libs/clangsupport/refactoringclientinterface.h @@ -47,10 +47,8 @@ public: void dispatch(const MessageEnvelop &messageEnvelop) override; virtual void alive() = 0; - virtual void sourceLocationsForRenamingMessage(SourceLocationsForRenamingMessage &&message) = 0; virtual void sourceRangesAndDiagnosticsForQueryMessage(SourceRangesAndDiagnosticsForQueryMessage &&message) = 0; virtual void sourceRangesForQueryMessage(SourceRangesForQueryMessage &&message) = 0; - virtual void setLocalRenamingCallback(RenameCallback &&localRenamingCallback) = 0; virtual void progress(ProgressMessage &&message) = 0; protected: diff --git a/src/libs/clangsupport/refactoringclientproxy.cpp b/src/libs/clangsupport/refactoringclientproxy.cpp index 646cb0e161..b2d30d7bfb 100644 --- a/src/libs/clangsupport/refactoringclientproxy.cpp +++ b/src/libs/clangsupport/refactoringclientproxy.cpp @@ -66,11 +66,6 @@ void RefactoringClientProxy::alive() writeMessageBlock.write(AliveMessage()); } -void RefactoringClientProxy::sourceLocationsForRenamingMessage(SourceLocationsForRenamingMessage &&message) -{ - writeMessageBlock.write(message); -} - void RefactoringClientProxy::sourceRangesAndDiagnosticsForQueryMessage(SourceRangesAndDiagnosticsForQueryMessage &&message) { writeMessageBlock.write(message); diff --git a/src/libs/clangsupport/refactoringclientproxy.h b/src/libs/clangsupport/refactoringclientproxy.h index 07cba05e8d..371ae91f82 100644 --- a/src/libs/clangsupport/refactoringclientproxy.h +++ b/src/libs/clangsupport/refactoringclientproxy.h @@ -50,13 +50,10 @@ public: void readMessages(); void alive() override; - void sourceLocationsForRenamingMessage(SourceLocationsForRenamingMessage &&message) override; void sourceRangesAndDiagnosticsForQueryMessage(SourceRangesAndDiagnosticsForQueryMessage &&message) override; void sourceRangesForQueryMessage(SourceRangesForQueryMessage &&message) override; void progress(ProgressMessage &&message) override; - void setLocalRenamingCallback(RenameCallback &&) final {} - private: ClangBackEnd::WriteMessageBlock writeMessageBlock; ClangBackEnd::ReadMessageBlock readMessageBlock; diff --git a/src/libs/clangsupport/refactoringserverinterface.cpp b/src/libs/clangsupport/refactoringserverinterface.cpp index a95837f80a..6fcaa0f054 100644 --- a/src/libs/clangsupport/refactoringserverinterface.cpp +++ b/src/libs/clangsupport/refactoringserverinterface.cpp @@ -38,9 +38,6 @@ void RefactoringServerInterface::dispatch(const MessageEnvelop &messageEnvelop) case MessageType::EndMessage: end(); break; - case MessageType::RequestSourceLocationsForRenamingMessage: - requestSourceLocationsForRenamingMessage(messageEnvelop.message<RequestSourceLocationsForRenamingMessage>()); - break; case MessageType::RequestSourceRangesAndDiagnosticsForQueryMessage: requestSourceRangesAndDiagnosticsForQueryMessage(messageEnvelop.message<RequestSourceRangesAndDiagnosticsForQueryMessage>()); break; diff --git a/src/libs/clangsupport/refactoringserverinterface.h b/src/libs/clangsupport/refactoringserverinterface.h index 2dcc503860..a8a677427c 100644 --- a/src/libs/clangsupport/refactoringserverinterface.h +++ b/src/libs/clangsupport/refactoringserverinterface.h @@ -32,7 +32,6 @@ namespace ClangBackEnd { class RefactoringClientInterface; -class RequestSourceLocationsForRenamingMessage; class RequestSourceRangesAndDiagnosticsForQueryMessage; class RequestSourceRangesForQueryMessage; class CancelMessage; @@ -46,7 +45,6 @@ public: void dispatch(const MessageEnvelop &messageEnvelop) override; virtual void end() = 0; - virtual void requestSourceLocationsForRenamingMessage(RequestSourceLocationsForRenamingMessage &&message) = 0; virtual void requestSourceRangesAndDiagnosticsForQueryMessage(RequestSourceRangesAndDiagnosticsForQueryMessage &&message) = 0; virtual void requestSourceRangesForQueryMessage(RequestSourceRangesForQueryMessage &&message) = 0; virtual void cancel() = 0; diff --git a/src/libs/clangsupport/refactoringserverproxy.cpp b/src/libs/clangsupport/refactoringserverproxy.cpp index 2208f3a0ce..a206a2531b 100644 --- a/src/libs/clangsupport/refactoringserverproxy.cpp +++ b/src/libs/clangsupport/refactoringserverproxy.cpp @@ -50,11 +50,6 @@ void RefactoringServerProxy::end() m_writeMessageBlock.write(EndMessage()); } -void RefactoringServerProxy::requestSourceLocationsForRenamingMessage(RequestSourceLocationsForRenamingMessage &&message) -{ - m_writeMessageBlock.write(message); -} - void RefactoringServerProxy::requestSourceRangesAndDiagnosticsForQueryMessage(RequestSourceRangesAndDiagnosticsForQueryMessage &&message) { m_writeMessageBlock.write(message); diff --git a/src/libs/clangsupport/refactoringserverproxy.h b/src/libs/clangsupport/refactoringserverproxy.h index 34861767d8..4b91036c46 100644 --- a/src/libs/clangsupport/refactoringserverproxy.h +++ b/src/libs/clangsupport/refactoringserverproxy.h @@ -52,7 +52,6 @@ public: explicit RefactoringServerProxy(RefactoringClientInterface *client, QIODevice *ioDevice); void end() override; - void requestSourceLocationsForRenamingMessage(RequestSourceLocationsForRenamingMessage &&message) override; void requestSourceRangesAndDiagnosticsForQueryMessage(RequestSourceRangesAndDiagnosticsForQueryMessage &&message) override; void requestSourceRangesForQueryMessage(RequestSourceRangesForQueryMessage &&message) override; void updateProjectParts(UpdateProjectPartsMessage &&message) override; diff --git a/src/libs/clangsupport/requestsourcelocationforrenamingmessage.cpp b/src/libs/clangsupport/requestsourcelocationforrenamingmessage.cpp deleted file mode 100644 index dd25a3ebae..0000000000 --- a/src/libs/clangsupport/requestsourcelocationforrenamingmessage.cpp +++ /dev/null @@ -1,41 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt Creator. -** -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -****************************************************************************/ - -#include "requestsourcelocationforrenamingmessage.h" - -namespace ClangBackEnd { - -QDebug operator<<(QDebug debug, const RequestSourceLocationsForRenamingMessage &message) -{ - debug.nospace() << "RequestSourceLocationsForRenamingMessage(" - << message.filePath << ", " - << message.line << ", " - << message.column << ", " - << message.unsavedContent << ")"; - - return debug; -} - -} // namespace ClangBackEnd diff --git a/src/libs/clangsupport/requestsourcelocationforrenamingmessage.h b/src/libs/clangsupport/requestsourcelocationforrenamingmessage.h deleted file mode 100644 index 9082e0dfaf..0000000000 --- a/src/libs/clangsupport/requestsourcelocationforrenamingmessage.h +++ /dev/null @@ -1,108 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt Creator. -** -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -****************************************************************************/ - -#pragma once - -#include "clangsupport_global.h" -#include "filepath.h" - -#include <utils/smallstringvector.h> - -namespace ClangBackEnd { - -class CLANGSUPPORT_EXPORT RequestSourceLocationsForRenamingMessage -{ -public: - RequestSourceLocationsForRenamingMessage() = default; - RequestSourceLocationsForRenamingMessage(FilePath &&filePath, - uint line, - uint column, - Utils::SmallString &&unsavedContent, - Utils::SmallStringVector &&commandLine, - int textDocumentRevision) - : filePath(std::move(filePath)), - unsavedContent(std::move(unsavedContent)), - commandLine(std::move(commandLine)), - line(line), - column(column), - textDocumentRevision(textDocumentRevision) - {} - - friend QDataStream &operator<<(QDataStream &out, const RequestSourceLocationsForRenamingMessage &message) - { - out << message.filePath; - out << message.unsavedContent; - out << message.commandLine; - out << message.line; - out << message.column; - out << message.textDocumentRevision; - - return out; - } - - friend QDataStream &operator>>(QDataStream &in, RequestSourceLocationsForRenamingMessage &message) - { - in >> message.filePath; - in >> message.unsavedContent; - in >> message.commandLine; - in >> message.line; - in >> message.column; - in >> message.textDocumentRevision; - - return in; - } - - friend bool operator==(const RequestSourceLocationsForRenamingMessage &first, const RequestSourceLocationsForRenamingMessage &second) - { - return first.filePath == second.filePath - && first.line == second.line - && first.column == second.column - && first.textDocumentRevision == second.textDocumentRevision - && first.unsavedContent == second.unsavedContent - && first.commandLine == second.commandLine; - } - - RequestSourceLocationsForRenamingMessage clone() const - { - return RequestSourceLocationsForRenamingMessage(filePath.clone(), - line, column, - unsavedContent.clone(), - commandLine.clone(), - textDocumentRevision); - } - -public: - FilePath filePath; - Utils::SmallString unsavedContent; - Utils::SmallStringVector commandLine; - uint line = 1; - uint column = 1; - int textDocumentRevision = 1; -}; - -CLANGSUPPORT_EXPORT QDebug operator<<(QDebug debug, const RequestSourceLocationsForRenamingMessage &message); - -DECLARE_MESSAGE(RequestSourceLocationsForRenamingMessage) -} // namespace ClangBackEnd diff --git a/src/libs/clangsupport/sourcelocationsforrenamingmessage.cpp b/src/libs/clangsupport/sourcelocationsforrenamingmessage.cpp deleted file mode 100644 index 3490738531..0000000000 --- a/src/libs/clangsupport/sourcelocationsforrenamingmessage.cpp +++ /dev/null @@ -1,39 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt Creator. -** -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -****************************************************************************/ - -#include "sourcelocationsforrenamingmessage.h" - -namespace ClangBackEnd { - -QDebug operator<<(QDebug debug, const SourceLocationsForRenamingMessage &message) -{ - debug.nospace() << "SourceLocationsForRenamingMessage(" - << message.sourceLocations - << ")"; - - return debug; -} - -} // namespace ClangBackEnd diff --git a/src/libs/clangsupport/sourcelocationsforrenamingmessage.h b/src/libs/clangsupport/sourcelocationsforrenamingmessage.h deleted file mode 100644 index 5be072677c..0000000000 --- a/src/libs/clangsupport/sourcelocationsforrenamingmessage.h +++ /dev/null @@ -1,87 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt Creator. -** -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -****************************************************************************/ - -#pragma once - -#include "sourcelocationscontainer.h" - -#include <utils/smallstring.h> - -namespace ClangBackEnd { - -class SourceLocationsForRenamingMessage -{ -public: - SourceLocationsForRenamingMessage() = default; - SourceLocationsForRenamingMessage(Utils::SmallString &&symbolName, - SourceLocationsContainer &&sourceLocationContainer, - int textDocumentRevision) - : symbolName(std::move(symbolName)), - sourceLocations(std::move(sourceLocationContainer)), - textDocumentRevision(textDocumentRevision) - {} - - friend QDataStream &operator<<(QDataStream &out, const SourceLocationsForRenamingMessage &message) - { - out << message.symbolName; - out << message.sourceLocations; - out << message.textDocumentRevision; - - return out; - } - - friend QDataStream &operator>>(QDataStream &in, SourceLocationsForRenamingMessage &message) - { - in >> message.symbolName; - in >> message.sourceLocations; - in >> message.textDocumentRevision; - - return in; - } - - friend bool operator==(const SourceLocationsForRenamingMessage &first, const SourceLocationsForRenamingMessage &second) - { - return first.textDocumentRevision == second.textDocumentRevision - && first.symbolName == second.symbolName - && first.sourceLocations == second.sourceLocations; - } - - SourceLocationsForRenamingMessage clone() const - { - return SourceLocationsForRenamingMessage(symbolName.clone(), - sourceLocations.clone(), - textDocumentRevision); - } - -public: - Utils::SmallString symbolName; - SourceLocationsContainer sourceLocations; - int textDocumentRevision = 0; -}; - -CLANGSUPPORT_EXPORT QDebug operator<<(QDebug debug, const SourceLocationsForRenamingMessage &message); - -DECLARE_MESSAGE(SourceLocationsForRenamingMessage) -} // namespace ClangBackEnd diff --git a/src/libs/cplusplus/LookupContext.cpp b/src/libs/cplusplus/LookupContext.cpp index 026b293e2d..5a187e4f1d 100644 --- a/src/libs/cplusplus/LookupContext.cpp +++ b/src/libs/cplusplus/LookupContext.cpp @@ -37,6 +37,8 @@ #include <cplusplus/Scope.h> #include <cplusplus/Control.h> +#include <utils/algorithm.h> + #include <QStack> #include <QHash> #include <QVarLengthArray> @@ -1175,7 +1177,7 @@ ClassOrNamespace *ClassOrNamespace::nestedType(const Name *name, if (!name->isTemplateNameId()) _alreadyConsideredClasses.insert(referenceClass); - QSet<ClassOrNamespace *> knownUsings = reference->usings().toSet(); + QSet<ClassOrNamespace *> knownUsings = Utils::toSet(reference->usings()); // If we are dealling with a template type, more work is required, since we need to // construct all instantiation data. diff --git a/src/libs/modelinglib/qmt/diagram_scene/diagramscenemodel.cpp b/src/libs/modelinglib/qmt/diagram_scene/diagramscenemodel.cpp index f4dbd24c1a..3587fc366b 100644 --- a/src/libs/modelinglib/qmt/diagram_scene/diagramscenemodel.cpp +++ b/src/libs/modelinglib/qmt/diagram_scene/diagramscenemodel.cpp @@ -50,6 +50,8 @@ #include "qmt/tasks/diagramscenecontroller.h" #include "qmt/tasks/ielementtasks.h" +#include <utils/algorithm.h> + #include <QSet> #include <QGraphicsItem> #include <QGraphicsSceneMouseEvent> @@ -514,8 +516,8 @@ bool DiagramSceneModel::exportSvg(const QString &fileName, bool selectedElements return true; #else // QT_NO_SVG - Q_UNUSED(fileName); - Q_UNUSED(selectedElements); + Q_UNUSED(fileName) + Q_UNUSED(selectedElements) return false; #endif // QT_NO_SVG } @@ -639,7 +641,7 @@ void DiagramSceneModel::keyReleaseEvent(QKeyEvent *event) void DiagramSceneModel::mousePressEvent(QGraphicsSceneMouseEvent *event) { - updateFocusItem(QSet<QGraphicsItem *>::fromList(m_graphicsScene->selectedItems())); + updateFocusItem(Utils::toSet(m_graphicsScene->selectedItems())); m_latchController->mousePressEventLatching(event); mousePressEventReparenting(event); } @@ -681,7 +683,7 @@ void DiagramSceneModel::mouseReleaseEventReparenting(QGraphicsSceneMouseEvent *e if (event->modifiers() & Qt::AltModifier) { ModelController *modelController = diagramController()->modelController(); MPackage *newOwner = nullptr; - QSet<QGraphicsItem *> selectedItemSet = m_graphicsScene->selectedItems().toSet(); + QSet<QGraphicsItem *> selectedItemSet = Utils::toSet(m_graphicsScene->selectedItems()); QList<QGraphicsItem *> itemsUnderMouse = m_graphicsScene->items(event->scenePos()); foreach (QGraphicsItem *item, itemsUnderMouse) { if (!selectedItemSet.contains(item)) { @@ -840,7 +842,7 @@ void DiagramSceneModel::onSelectionChanged() bool selectionChanged = false; // collect and update all primary selected items (selected by user) - QSet<QGraphicsItem *> newSelectedItems = QSet<QGraphicsItem *>::fromList(m_graphicsScene->selectedItems()); + QSet<QGraphicsItem *> newSelectedItems = Utils::toSet(m_graphicsScene->selectedItems()); updateFocusItem(newSelectedItems); foreach (QGraphicsItem *item, m_selectedItems) { if (!newSelectedItems.contains(item)) { diff --git a/src/libs/modelinglib/qmt/diagram_scene/items/classitem.cpp b/src/libs/modelinglib/qmt/diagram_scene/items/classitem.cpp index 04b3acd77e..9c5345c417 100644 --- a/src/libs/modelinglib/qmt/diagram_scene/items/classitem.cpp +++ b/src/libs/modelinglib/qmt/diagram_scene/items/classitem.cpp @@ -52,6 +52,8 @@ #include "qmt/tasks/diagramscenecontroller.h" #include "qmt/tasks/ielementtasks.h" +#include <utils/algorithm.h> + #include <QGraphicsScene> #include <QGraphicsRectItem> #include <QGraphicsSimpleTextItem> @@ -346,7 +348,7 @@ void ClassItem::relationDrawn(const QString &id, ObjectItem *targetItem, const Q { CustomRelation::Relationship::Aggregation, MAssociationEnd::Aggregation }, { CustomRelation::Relationship::Composition, MAssociationEnd::Composition } }; diagramSceneController->modelController()->startUpdateRelation(mAssociation); - mAssociation->setStereotypes(customRelation.stereotypes().toList()); + mAssociation->setStereotypes(Utils::toList(customRelation.stereotypes())); mAssociation->setName(customRelation.name()); MAssociationEnd endA; endA.setCardinality(customRelation.endA().cardinality()); diff --git a/src/libs/modelinglib/qmt/stereotype/stereotypecontroller.cpp b/src/libs/modelinglib/qmt/stereotype/stereotypecontroller.cpp index 9d1640ff6a..ae1974717b 100644 --- a/src/libs/modelinglib/qmt/stereotype/stereotypecontroller.cpp +++ b/src/libs/modelinglib/qmt/stereotype/stereotypecontroller.cpp @@ -130,7 +130,7 @@ QList<QString> StereotypeController::knownStereotypes(StereotypeIcon::Element st if (icon.elements().isEmpty() || icon.elements().contains(stereotypeElement)) stereotypes += icon.stereotypes(); } - QList<QString> list = stereotypes.toList(); + QList<QString> list = Utils::toList(stereotypes); std::sort(list.begin(), list.end()); return list; } diff --git a/src/libs/qmldebug/qmldebugconnection.cpp b/src/libs/qmldebug/qmldebugconnection.cpp index 143277b379..629360a8bc 100644 --- a/src/libs/qmldebug/qmldebugconnection.cpp +++ b/src/libs/qmldebug/qmldebugconnection.cpp @@ -35,6 +35,8 @@ #include <QTcpServer> #include <QTcpSocket> +Q_DECLARE_METATYPE(QLocalSocket::LocalSocketError) + namespace QmlDebug { const int protocolVersion = 1; @@ -244,6 +246,11 @@ void QmlDebugConnection::protocolReadyRead() QmlDebugConnection::QmlDebugConnection(QObject *parent) : QObject(parent), d_ptr(new QmlDebugConnectionPrivate) { + static const int metaTypes[] = { + qRegisterMetaType<QAbstractSocket::SocketError>(), + qRegisterMetaType<QLocalSocket::LocalSocketError>() + }; + Q_UNUSED(metaTypes); } QmlDebugConnection::~QmlDebugConnection() @@ -343,9 +350,10 @@ void QmlDebugConnection::connectToHost(const QString &hostName, quint16 port) this, [this](QAbstractSocket::SocketError error) { emit logError(socketErrorToString(error)); socketDisconnected(); - }); + }, Qt::QueuedConnection); connect(socket, &QAbstractSocket::connected, this, &QmlDebugConnection::socketConnected); - connect(socket, &QAbstractSocket::disconnected, this, &QmlDebugConnection::socketDisconnected); + connect(socket, &QAbstractSocket::disconnected, this, &QmlDebugConnection::socketDisconnected, + Qt::QueuedConnection); socket->connectToHost(hostName.isEmpty() ? QString("localhost") : hostName, port); } @@ -376,13 +384,14 @@ void QmlDebugConnection::newConnection() QObject::connect(d->protocol, &QPacketProtocol::readyRead, this, &QmlDebugConnection::protocolReadyRead); - connect(socket, &QLocalSocket::disconnected, this, &QmlDebugConnection::socketDisconnected); + connect(socket, &QLocalSocket::disconnected, this, &QmlDebugConnection::socketDisconnected, + Qt::QueuedConnection); connect(socket, QOverload<QLocalSocket::LocalSocketError>::of(&QLocalSocket::error), this, [this](QLocalSocket::LocalSocketError error) { emit logError(socketErrorToString(static_cast<QAbstractSocket::SocketError>(error))); socketDisconnected(); - }); + }, Qt::QueuedConnection); connect(socket, &QLocalSocket::stateChanged, this, [this](QLocalSocket::LocalSocketState state) { diff --git a/src/libs/qmljs/qmljscheck.cpp b/src/libs/qmljs/qmljscheck.cpp index e5243830cd..cd6d024443 100644 --- a/src/libs/qmljs/qmljscheck.cpp +++ b/src/libs/qmljs/qmljscheck.cpp @@ -29,6 +29,7 @@ #include "qmljsutils.h" #include "parser/qmljsast_p.h" +#include <utils/algorithm.h> #include <utils/qtcassert.h> #include <QColor> @@ -666,7 +667,7 @@ Check::Check(Document::Ptr doc, const ContextPtr &context) _isQtQuick2 = isQtQuick2(); } - _enabledMessages = Message::allMessageTypes().toSet(); + _enabledMessages = Utils::toSet(Message::allMessageTypes()); disableMessage(HintAnonymousFunctionSpacing); disableMessage(HintDeclareVarsInOneLine); disableMessage(HintDeclarationsShouldBeAtStartOfFunction); @@ -1539,7 +1540,7 @@ void Check::scanCommentsForAnnotations() // enable all checks annotation if (comment.contains("@enable-all-checks")) - _enabledMessages = Message::allMessageTypes().toSet(); + _enabledMessages = Utils::toSet(Message::allMessageTypes()); // find all disable annotations int lastOffset = -1; diff --git a/src/libs/qmljs/qmljsimportdependencies.cpp b/src/libs/qmljs/qmljsimportdependencies.cpp index afa8d58b3a..3f17846dab 100644 --- a/src/libs/qmljs/qmljsimportdependencies.cpp +++ b/src/libs/qmljs/qmljsimportdependencies.cpp @@ -27,6 +27,7 @@ #include "qmljsinterpreter.h" #include "qmljsviewercontext.h" +#include <utils/algorithm.h> #include <utils/qrcparser.h> #include <utils/qtcassert.h> @@ -521,7 +522,7 @@ QByteArray DependencyInfo::calculateFingerprint(const ImportDependencies &deps) { QCryptographicHash hash(QCryptographicHash::Sha1); rootImport.addToHash(hash); - QStringList coreImports = allCoreImports.toList(); + QStringList coreImports = Utils::toList(allCoreImports); coreImports.sort(); foreach (const QString importId, coreImports) { hash.addData(reinterpret_cast<const char*>(importId.constData()), importId.size() * sizeof(QChar)); @@ -529,9 +530,9 @@ QByteArray DependencyInfo::calculateFingerprint(const ImportDependencies &deps) hash.addData(coreImportFingerprint); } hash.addData("/", 1); - QList<ImportKey> imports(allImports.toList()); + QList<ImportKey> imports = Utils::toList(allImports); std::sort(imports.begin(), imports.end()); - foreach (const ImportKey &k, imports) + for (const ImportKey &k : qAsConst(imports)) k.addToHash(hash); return hash.result(); } diff --git a/src/libs/qmljs/qmljsplugindumper.cpp b/src/libs/qmljs/qmljsplugindumper.cpp index aeef89372f..2c6afb61c0 100644 --- a/src/libs/qmljs/qmljsplugindumper.cpp +++ b/src/libs/qmljs/qmljsplugindumper.cpp @@ -29,8 +29,8 @@ #include <qmljs/qmljsinterpreter.h> #include <qmljs/qmljsviewercontext.h> -//#include <projectexplorer/session.h> -//#include <coreplugin/messagemanager.h> + +#include <utils/algorithm.h> #include <utils/filesystemwatcher.h> #include <utils/fileutils.h> #include <utils/hostosinfo.h> @@ -437,7 +437,7 @@ void PluginDumper::loadDependencies(const QStringList &dependencies, } QStringList newDependencies; loadQmlTypeDescription(dependenciesPaths, errors, warnings, objects, 0, &newDependencies); - newDependencies = (newDependencies.toSet() - *visitedPtr).toList(); + newDependencies = Utils::toList(Utils::toSet(newDependencies) - *visitedPtr); if (!newDependencies.isEmpty()) loadDependencies(newDependencies, errors, warnings, objects, visitedPtr.take()); } diff --git a/src/libs/utils/algorithm.h b/src/libs/utils/algorithm.h index 4b7231cca0..1e821a4bcb 100644 --- a/src/libs/utils/algorithm.h +++ b/src/libs/utils/algorithm.h @@ -1259,4 +1259,27 @@ OutputIterator set_union(InputIterator1 first1, return Utils::set_union_impl( first1, last1, first2, last2, result, std::less<typename InputIterator1::value_type>{}); } + +// Replacement for deprecated Qt functionality + +template <class T> +QSet<T> toSet(const QList<T> &list) +{ +#if (QT_VERSION < QT_VERSION_CHECK(5, 14, 0)) + return list.toSet(); +#else + return QSet<T>(list.begin(), list.end()); +#endif +} + +template <class T> +QList<T> toList(const QSet<T> &set) +{ +#if (QT_VERSION < QT_VERSION_CHECK(5, 14, 0)) + return set.toList(); +#else + return QList<T>(set.begin(), set.end()); +#endif +} + } // namespace Utils diff --git a/src/libs/utils/codegeneration.cpp b/src/libs/utils/codegeneration.cpp index 5843e843d9..697d876e0b 100644 --- a/src/libs/utils/codegeneration.cpp +++ b/src/libs/utils/codegeneration.cpp @@ -121,23 +121,23 @@ void writeQtIncludeSection(const QStringList &qt4, qt4Only.subtract(common); qt5Only.subtract(common); - qtSection(common.toList(), str); + qtSection(Utils::toList(common), str); if (!qt4Only.isEmpty() || !qt5Only.isEmpty()) { if (addQtVersionCheck) writeBeginQtVersionCheck(str); - qtSection(qt5Only.toList(), str); + qtSection(Utils::toList(qt5Only), str); if (addQtVersionCheck) str << QLatin1String("#else\n"); - qtSection(qt4Only.toList(), str); + qtSection(Utils::toList(qt4Only), str); if (addQtVersionCheck) str << QLatin1String("#endif\n"); } } else { if (!qt5Only.isEmpty()) // default to Qt5 - qtSection(qt5Only.toList(), str); + qtSection(Utils::toList(qt5Only), str); else - qtSection(qt4Only.toList(), str); + qtSection(Utils::toList(qt4Only), str); } } diff --git a/src/libs/utils/synchronousprocess.cpp b/src/libs/utils/synchronousprocess.cpp index 82004b8729..f197494b4c 100644 --- a/src/libs/utils/synchronousprocess.cpp +++ b/src/libs/utils/synchronousprocess.cpp @@ -24,16 +24,18 @@ ****************************************************************************/ #include "synchronousprocess.h" -#include "qtcassert.h" +#include "executeondestruction.h" #include "hostosinfo.h" -#include "fileutils.h" +#include "qtcassert.h" +#include "qtcprocess.h" #include <QDebug> -#include <QTimer> -#include <QTextCodec> #include <QDir> +#include <QLoggingCategory> #include <QMessageBox> +#include <QTextCodec> #include <QThread> +#include <QTimer> #include <QApplication> @@ -82,6 +84,8 @@ enum { defaultMaxHangTimerCount = 10 }; namespace Utils { +Q_LOGGING_CATEGORY(processLog, "qtc.utils.synchronousprocess", QtWarningMsg); + // A special QProcess derivative allowing for terminal control. class TerminalControllingProcess : public QProcess { public: @@ -445,8 +449,10 @@ static bool isGuiThread() SynchronousProcessResponse SynchronousProcess::run(const CommandLine &cmd, const QByteArray &writeData) { - if (debug) - qDebug() << '>' << Q_FUNC_INFO << cmd.toUserOutput(); + qCDebug(processLog).noquote() << "Starting:" << cmd.toUserOutput(); + ExecuteOnDestruction logResult([this] { + qCDebug(processLog) << d->m_result; + }); d->clearForRun(); @@ -492,13 +498,16 @@ SynchronousProcessResponse SynchronousProcess::run(const CommandLine &cmd, QApplication::restoreOverrideCursor(); } - if (debug) - qDebug() << '<' << Q_FUNC_INFO << cmd.executable().toString() << d->m_result; return d->m_result; } SynchronousProcessResponse SynchronousProcess::runBlocking(const CommandLine &cmd) { + qCDebug(processLog).noquote() << "Starting blocking:" << cmd.toUserOutput(); + ExecuteOnDestruction logResult([this] { + qCDebug(processLog) << d->m_result; + }); + d->clearForRun(); // On Windows, start failure is triggered immediately if the diff --git a/src/plugins/android/androiddebugsupport.cpp b/src/plugins/android/androiddebugsupport.cpp index 09368133f3..632f68e9cf 100644 --- a/src/plugins/android/androiddebugsupport.cpp +++ b/src/plugins/android/androiddebugsupport.cpp @@ -82,15 +82,15 @@ static QStringList qtSoPaths(QtSupport::BaseQtVersion *qtVersion) paths.insert(it.fileInfo().absolutePath()); } } - return paths.toList(); + return Utils::toList(paths); } static QStringList uniquePaths(const QStringList &files) { QSet<QString> paths; - foreach (const QString &file, files) - paths<<QFileInfo(file).absolutePath(); - return paths.toList(); + for (const QString &file : files) + paths << QFileInfo(file).absolutePath(); + return Utils::toList(paths); } static QStringList getSoLibSearchPath(const ProjectNode *node) diff --git a/src/plugins/android/androidmanifesteditorwidget.cpp b/src/plugins/android/androidmanifesteditorwidget.cpp index 72ab0c9984..d8e8b003c6 100644 --- a/src/plugins/android/androidmanifesteditorwidget.cpp +++ b/src/plugins/android/androidmanifesteditorwidget.cpp @@ -45,6 +45,7 @@ #include <texteditor/texteditoractionhandler.h> #include <texteditor/texteditor.h> + #include <utils/algorithm.h> #include <utils/utilsicons.h> @@ -924,7 +925,7 @@ void AndroidManifestEditorWidget::parseManifest(QXmlStreamReader &reader, QXmlSt QXmlStreamAttributes result = modifyXmlStreamAttributes(attributes, keys, values); writer.writeAttributes(result); - QSet<QString> permissions = m_permissionsModel->permissions().toSet(); + QSet<QString> permissions = Utils::toSet(m_permissionsModel->permissions()); bool foundUsesSdk = false; bool foundPermissionComment = false; diff --git a/src/plugins/android/androidsdkmodel.cpp b/src/plugins/android/androidsdkmodel.cpp index b72810688b..5506ad2378 100644 --- a/src/plugins/android/androidsdkmodel.cpp +++ b/src/plugins/android/androidsdkmodel.cpp @@ -306,7 +306,7 @@ void AndroidSdkModel::selectMissingEssentials() QList<const AndroidSdkPackage *> AndroidSdkModel::userSelection() const { - return m_changeState.toList(); + return Utils::toList(m_changeState); } void AndroidSdkModel::resetSelection() diff --git a/src/plugins/autotest/gtest/gtestconfiguration.cpp b/src/plugins/autotest/gtest/gtestconfiguration.cpp index 8297289407..49f151da58 100644 --- a/src/plugins/autotest/gtest/gtestconfiguration.cpp +++ b/src/plugins/autotest/gtest/gtestconfiguration.cpp @@ -58,18 +58,18 @@ QStringList filterInterfering(const QStringList &provided, QStringList *omitted) "--gtest_print_time=" }; - QSet<QString> allowed = Utils::filtered(provided.toSet(), [] (const QString &arg) { + QSet<QString> allowed = Utils::filtered(Utils::toSet(provided), [] (const QString &arg) { return Utils::allOf(knownInterferingOptions, [&arg] (const QString &interfering) { return !arg.startsWith(interfering); }); }); if (omitted) { - QSet<QString> providedSet = provided.toSet(); + QSet<QString> providedSet = Utils::toSet(provided); providedSet.subtract(allowed); - omitted->append(providedSet.toList()); + omitted->append(Utils::toList(providedSet)); } - return allowed.toList(); + return Utils::toList(allowed); } QStringList GTestConfiguration::argumentsForTestRunner(QStringList *omitted) const diff --git a/src/plugins/autotest/qtest/qttestparser.cpp b/src/plugins/autotest/qtest/qttestparser.cpp index ddedf4dc52..f03d9da923 100644 --- a/src/plugins/autotest/qtest/qttestparser.cpp +++ b/src/plugins/autotest/qtest/qttestparser.cpp @@ -239,7 +239,7 @@ static void fetchAndMergeBaseTestFunctions(const QSet<QString> &baseClasses, const CPlusPlus::Document::Ptr &doc, const CPlusPlus::Snapshot &snapshot) { - QList<QString> bases = baseClasses.toList(); + QList<QString> bases = Utils::toList(baseClasses); while (!bases.empty()) { const QString base = bases.takeFirst(); TestVisitor baseVisitor(base, snapshot); @@ -250,7 +250,7 @@ static void fetchAndMergeBaseTestFunctions(const QSet<QString> &baseClasses, baseVisitor.accept(declaringDoc->globalNamespace()); if (!baseVisitor.resultValid()) continue; - bases.append(baseVisitor.baseClasses().toList()); + bases.append(Utils::toList(baseVisitor.baseClasses())); mergeTestFunctions(testFunctions, baseVisitor.privateSlots()); } } diff --git a/src/plugins/baremetal/iarewtoolchain.cpp b/src/plugins/baremetal/iarewtoolchain.cpp index ad70d78b16..79ed42e14e 100644 --- a/src/plugins/baremetal/iarewtoolchain.cpp +++ b/src/plugins/baremetal/iarewtoolchain.cpp @@ -87,7 +87,7 @@ static Macros dumpPredefinedMacros(const FilePath &compiler, const Core::Id lang CommandLine cmd(compiler, {fakeIn.fileName()}); if (languageId == ProjectExplorer::Constants::CXX_LANGUAGE_ID) - cmd.addArg("--ec++"); + cmd.addArg("--c++"); cmd.addArg("--predef_macros"); cmd.addArg(outpath); @@ -132,7 +132,7 @@ static HeaderPaths dumpHeaderPaths(const FilePath &compiler, const Core::Id lang CommandLine cmd(compiler, {fakeIn.fileName()}); if (languageId == ProjectExplorer::Constants::CXX_LANGUAGE_ID) - cmd.addArg("--ec++"); + cmd.addArg("--c++"); cmd.addArg("--preinclude"); cmd.addArg("."); diff --git a/src/plugins/clangcodemodel/clangbackendcommunicator.cpp b/src/plugins/clangcodemodel/clangbackendcommunicator.cpp index 28a31f0553..c411e0cfdf 100644 --- a/src/plugins/clangcodemodel/clangbackendcommunicator.cpp +++ b/src/plugins/clangcodemodel/clangbackendcommunicator.cpp @@ -252,7 +252,7 @@ void BackendCommunicator::documentsChangedFromCppEditorDocument(const QString &f documentsChanged(filePath, document->contents(), document->revision()); } -void BackendCommunicator::unsavedFielsUpdatedFromCppEditorDocument(const QString &filePath) +void BackendCommunicator::unsavedFilesUpdatedFromCppEditorDocument(const QString &filePath) { const CppTools::CppEditorDocumentHandle *document = ClangCodeModel::Utils::cppDocument(filePath); QTC_ASSERT(document, return); @@ -387,7 +387,7 @@ void BackendCommunicator::unsavedFilesUpdated(Core::IDocument *document) { QTC_ASSERT(document, return); - unsavedFielsUpdatedFromCppEditorDocument(document->filePath().toString()); + unsavedFilesUpdatedFromCppEditorDocument(document->filePath().toString()); } void BackendCommunicator::onConnectedToBackend() diff --git a/src/plugins/clangcodemodel/clangbackendcommunicator.h b/src/plugins/clangcodemodel/clangbackendcommunicator.h index 58435d48a6..81f151581d 100644 --- a/src/plugins/clangcodemodel/clangbackendcommunicator.h +++ b/src/plugins/clangcodemodel/clangbackendcommunicator.h @@ -79,7 +79,7 @@ public: const QByteArray &contents, uint documentRevision); void unsavedFilesUpdated(const FileContainers &fileContainers); - void unsavedFielsUpdatedFromCppEditorDocument(const QString &filePath); + void unsavedFilesUpdatedFromCppEditorDocument(const QString &filePath); void unsavedFilesRemoved(const FileContainers &fileContainers); void requestCompletions(ClangCompletionAssistProcessor *assistProcessor, diff --git a/src/plugins/clangrefactoring/clangrefactoringplugin.cpp b/src/plugins/clangrefactoring/clangrefactoringplugin.cpp index 03917ebd13..4f7d34d800 100644 --- a/src/plugins/clangrefactoring/clangrefactoringplugin.cpp +++ b/src/plugins/clangrefactoring/clangrefactoringplugin.cpp @@ -96,10 +96,6 @@ public: SymbolQuery<QuerySqliteReadStatementFactory> symbolQuery{statementFactory}; ClangBackEnd::ProjectPartsStorage<Sqlite::Database> projectPartsStorage{database}; RefactoringEngine engine{connectionClient.serverProxy(), refactoringClient, filePathCache, symbolQuery}; - QtCreatorSearch qtCreatorSearch; - QtCreatorClangQueryFindFilter qtCreatorfindFilter{connectionClient.serverProxy(), - qtCreatorSearch, - refactoringClient}; QtCreatorRefactoringProjectUpdater projectUpdate{connectionClient.serverProxy(), ClangPchManagerPlugin::pchManagerClient(), filePathCache, @@ -123,7 +119,6 @@ bool ClangRefactoringPlugin::initialize(const QStringList & /*arguments*/, QStri d->refactoringClient.setRefactoringEngine(&d->engine); d->refactoringClient.setRefactoringConnectionClient(&d->connectionClient); - ExtensionSystem::PluginManager::addObject(&d->qtCreatorfindFilter); connectBackend(); startBackend(); @@ -142,7 +137,6 @@ void ClangRefactoringPlugin::extensionsInitialized() ExtensionSystem::IPlugin::ShutdownFlag ClangRefactoringPlugin::aboutToShutdown() { - ExtensionSystem::PluginManager::removeObject(&d->qtCreatorfindFilter); CppTools::CppModelManager::removeRefactoringEngine( CppTools::RefactoringEngineType::ClangRefactoring); d->refactoringClient.setRefactoringConnectionClient(nullptr); diff --git a/src/plugins/clangrefactoring/qtcreatorclangqueryfindfilter.cpp b/src/plugins/clangrefactoring/qtcreatorclangqueryfindfilter.cpp index b4ab35e851..05c378b196 100644 --- a/src/plugins/clangrefactoring/qtcreatorclangqueryfindfilter.cpp +++ b/src/plugins/clangrefactoring/qtcreatorclangqueryfindfilter.cpp @@ -130,7 +130,8 @@ void QtCreatorClangQueryFindFilter::prepareFind() const CppTools::ProjectInfo projectInfo = CppTools::CppModelManager::instance()->projectInfo(currentProject); - setProjectParts(projectInfo.projectParts().toStdVector()); + const QVector<CppTools::ProjectPart::Ptr> parts = projectInfo.projectParts(); + setProjectParts({parts.begin(), parts.end()}); setUnsavedContent(createUnsavedContents()); } diff --git a/src/plugins/clangrefactoring/refactoringclient.cpp b/src/plugins/clangrefactoring/refactoringclient.cpp index 3bdeb9dd53..e39e27a22a 100644 --- a/src/plugins/clangrefactoring/refactoringclient.cpp +++ b/src/plugins/clangrefactoring/refactoringclient.cpp @@ -40,16 +40,6 @@ void RefactoringClient::alive() m_connectionClient->resetProcessAliveTimer(); } -void RefactoringClient::sourceLocationsForRenamingMessage( - ClangBackEnd::SourceLocationsForRenamingMessage &&message) -{ - m_localRenamingCallback(message.symbolName.toQString(), - message.sourceLocations, - message.textDocumentRevision); - - m_refactoringEngine->setRefactoringEngineAvailable(true); -} - void RefactoringClient::sourceRangesAndDiagnosticsForQueryMessage( ClangBackEnd::SourceRangesAndDiagnosticsForQueryMessage &&message) { @@ -64,12 +54,6 @@ void RefactoringClient::sourceRangesForQueryMessage(ClangBackEnd::SourceRangesFo setResultCounterAndSendSearchIsFinishedIfFinished(); } -void RefactoringClient::setLocalRenamingCallback( - CppTools::RefactoringEngineInterface::RenameCallback &&localRenamingCallback) -{ - m_localRenamingCallback = std::move(localRenamingCallback); -} - void RefactoringClient::progress(ClangBackEnd::ProgressMessage &&message) { m_progressManager.setProgress(message.progress, message.total); @@ -100,11 +84,6 @@ void RefactoringClient::setClangQueryHighlighter(ClangQueryHighlighter *highligh m_clangQueryHighlighter = highlighter; } -bool RefactoringClient::hasValidLocalRenamingCallback() const -{ - return bool(m_localRenamingCallback); -} - void RefactoringClient::setExpectedResultCount(uint count) { m_expectedResultCount = count; diff --git a/src/plugins/clangrefactoring/refactoringclient.h b/src/plugins/clangrefactoring/refactoringclient.h index f3d9e218e5..a68fe39211 100644 --- a/src/plugins/clangrefactoring/refactoringclient.h +++ b/src/plugins/clangrefactoring/refactoringclient.h @@ -54,15 +54,11 @@ public: {} void alive() override; - void sourceLocationsForRenamingMessage( - ClangBackEnd::SourceLocationsForRenamingMessage &&message) override; void sourceRangesAndDiagnosticsForQueryMessage( ClangBackEnd::SourceRangesAndDiagnosticsForQueryMessage &&message) override; void sourceRangesForQueryMessage( ClangBackEnd::SourceRangesForQueryMessage &&message) override; - void setLocalRenamingCallback( - CppTools::RefactoringEngineInterface::RenameCallback &&localRenamingCallback) override; void progress(ClangBackEnd::ProgressMessage &&message) override; void setRefactoringEngine(ClangRefactoring::RefactoringEngine *refactoringEngine); @@ -71,8 +67,6 @@ public: void setClangQueryExampleHighlighter(ClangQueryExampleHighlighter *highlighter); void setClangQueryHighlighter(ClangQueryHighlighter *highlighter); - bool hasValidLocalRenamingCallback() const; - void setExpectedResultCount(uint count); uint expectedResultCount() const; uint resultCounter() const; @@ -90,7 +84,6 @@ private: void sendSearchIsFinished(); private: - CppTools::RefactoringEngineInterface::RenameCallback m_localRenamingCallback; ClangBackEnd::RefactoringConnectionClient *m_connectionClient = nullptr; SearchHandle *m_searchHandle = nullptr; RefactoringEngine *m_refactoringEngine = nullptr; diff --git a/src/plugins/clangrefactoring/refactoringengine.cpp b/src/plugins/clangrefactoring/refactoringengine.cpp index 38f857ef1c..cc9121331d 100644 --- a/src/plugins/clangrefactoring/refactoringengine.cpp +++ b/src/plugins/clangrefactoring/refactoringengine.cpp @@ -28,7 +28,6 @@ #include <filepath.h> #include <refactoringserverinterface.h> -#include <requestsourcelocationforrenamingmessage.h> #include <cpptools/compileroptionsbuilder.h> #include <cpptools/cpptoolsreuse.h> @@ -47,7 +46,6 @@ namespace ClangRefactoring { -using ClangBackEnd::RequestSourceLocationsForRenamingMessage; RefactoringEngine::RefactoringEngine(ClangBackEnd::RefactoringServerInterface &server, ClangBackEnd::RefactoringClientInterface &client, @@ -62,34 +60,10 @@ RefactoringEngine::RefactoringEngine(ClangBackEnd::RefactoringServerInterface &s RefactoringEngine::~RefactoringEngine() = default; -void RefactoringEngine::startLocalRenaming(const CppTools::CursorInEditor &data, - CppTools::ProjectPart *projectPart, - RenameCallback &&renameSymbolsCallback) +void RefactoringEngine::startLocalRenaming(const CppTools::CursorInEditor &, + CppTools::ProjectPart *, + RenameCallback &&) { - using CppTools::CompilerOptionsBuilder; - - setRefactoringEngineAvailable(false); - - m_client.setLocalRenamingCallback(std::move(renameSymbolsCallback)); - - QString filePath = data.filePath().toString(); - QTextCursor textCursor = data.cursor(); - CompilerOptionsBuilder optionsBuilder{*projectPart, CppTools::UseSystemHeader::Yes}; - Utils::SmallStringVector commandLine{optionsBuilder.build( - fileKindInProjectPart(projectPart, filePath), - CppTools::getPchUsage())}; - - commandLine.push_back(filePath); - - RequestSourceLocationsForRenamingMessage message(ClangBackEnd::FilePath(filePath), - uint(textCursor.blockNumber() + 1), - uint(textCursor.positionInBlock() + 1), - textCursor.document()->toPlainText(), - std::move(commandLine), - textCursor.document()->revision()); - - - m_server.requestSourceLocationsForRenamingMessage(std::move(message)); } CppTools::Usages RefactoringEngine::locationsAt(const CppTools::CursorInEditor &data) const diff --git a/src/plugins/clangtools/clangtoolsprojectsettings.cpp b/src/plugins/clangtools/clangtoolsprojectsettings.cpp index 55573c8ee6..862030b950 100644 --- a/src/plugins/clangtools/clangtoolsprojectsettings.cpp +++ b/src/plugins/clangtools/clangtoolsprojectsettings.cpp @@ -128,10 +128,10 @@ void ClangToolsProjectSettings::store() m_project->setNamedSettings(SETTINGS_KEY_DIAGNOSTIC_CONFIG, m_diagnosticConfig.toSetting()); m_project->setNamedSettings(SETTINGS_KEY_BUILD_BEFORE_ANALYSIS, m_buildBeforeAnalysis); - const QStringList dirs = Utils::transform(m_selectedDirs.toList(), &Utils::FilePath::toString); + const QStringList dirs = Utils::transform<QList>(m_selectedDirs, &Utils::FilePath::toString); m_project->setNamedSettings(SETTINGS_KEY_SELECTED_DIRS, dirs); - const QStringList files = Utils::transform(m_selectedFiles.toList(), &Utils::FilePath::toString); + const QStringList files = Utils::transform<QList>(m_selectedFiles, &Utils::FilePath::toString); m_project->setNamedSettings(SETTINGS_KEY_SELECTED_FILES, files); QVariantList list; diff --git a/src/plugins/classview/classviewparser.cpp b/src/plugins/classview/classviewparser.cpp index 34b6de2950..0ba865c7f2 100644 --- a/src/plugins/classview/classviewparser.cpp +++ b/src/plugins/classview/classviewparser.cpp @@ -587,8 +587,7 @@ void Parser::clearCache() void Parser::setFileList(const QStringList &fileList) { - d->fileList.clear(); - d->fileList = QSet<QString>::fromList(fileList); + d->fileList = ::Utils::toSet(fileList); } /*! diff --git a/src/plugins/cmakeprojectmanager/cmakeproject.cpp b/src/plugins/cmakeprojectmanager/cmakeproject.cpp index 9379875e64..5544965ece 100644 --- a/src/plugins/cmakeprojectmanager/cmakeproject.cpp +++ b/src/plugins/cmakeprojectmanager/cmakeproject.cpp @@ -339,7 +339,7 @@ void CMakeProject::updateProjectData(CMakeBuildConfiguration *bc) { CMakeConfigItem paths; paths.key = "ANDROID_SO_LIBS_PATHS"; - paths.values = res.toList(); + paths.values = Utils::toList(res); patchedConfig.append(paths); } diff --git a/src/plugins/cmakeprojectmanager/tealeafreader.cpp b/src/plugins/cmakeprojectmanager/tealeafreader.cpp index fb941604dd..a98d5b1eef 100644 --- a/src/plugins/cmakeprojectmanager/tealeafreader.cpp +++ b/src/plugins/cmakeprojectmanager/tealeafreader.cpp @@ -273,7 +273,7 @@ std::unique_ptr<CMakeProjectNode> TeaLeafReader::generateProjectTree( = Utils::filtered(bt.includeFiles, [this](const Utils::FilePath &fn) { return fn.isChildOf(m_parameters.sourceDirectory); }); - allIncludePathSet.unite(QSet<FilePath>::fromList(targetIncludePaths)); + allIncludePathSet.unite(Utils::toSet(targetIncludePaths)); } const QList<FilePath> allIncludePaths = allIncludePathSet.toList(); diff --git a/src/plugins/coreplugin/documentmanager.cpp b/src/plugins/coreplugin/documentmanager.cpp index bde6f8a4a8..3939703cb6 100644 --- a/src/plugins/coreplugin/documentmanager.cpp +++ b/src/plugins/coreplugin/documentmanager.cpp @@ -43,6 +43,7 @@ #include <extensionsystem/pluginmanager.h> +#include <utils/algorithm.h> #include <utils/fileutils.h> #include <utils/globalfilechangeblocker.h> #include <utils/hostosinfo.h> @@ -743,7 +744,7 @@ QString DocumentManager::allDocumentFactoryFiltersString(QString *allFilesFilter } } - QStringList filters = uniqueFilters.toList(); + QStringList filters = Utils::toList(uniqueFilters); filters.sort(); const QString allFiles = Utils::allFilesFilterString(); if (allFilesFilter) diff --git a/src/plugins/coreplugin/editormanager/editormanager.cpp b/src/plugins/coreplugin/editormanager/editormanager.cpp index a3b4493991..2c26d50214 100644 --- a/src/plugins/coreplugin/editormanager/editormanager.cpp +++ b/src/plugins/coreplugin/editormanager/editormanager.cpp @@ -1424,7 +1424,7 @@ bool EditorManagerPrivate::closeEditors(const QList<IEditor*> &editors, CloseFla return false; if (!rejectedList.isEmpty()) { closingFailed = true; - QSet<IEditor*> skipSet = DocumentModel::editorsForDocuments(rejectedList).toSet(); + QSet<IEditor*> skipSet = Utils::toSet(DocumentModel::editorsForDocuments(rejectedList)); acceptedEditors = acceptedEditors.subtract(skipSet); } } @@ -1490,7 +1490,7 @@ bool EditorManagerPrivate::closeEditors(const QList<IEditor*> &editors, CloseFla } } - emit m_instance->editorsClosed(acceptedEditors.toList()); + emit m_instance->editorsClosed(Utils::toList(acceptedEditors)); foreach (IEditor *editor, acceptedEditors) delete editor; diff --git a/src/plugins/coreplugin/id.cpp b/src/plugins/coreplugin/id.cpp index 6e081746ae..8e3523b6b9 100644 --- a/src/plugins/coreplugin/id.cpp +++ b/src/plugins/coreplugin/id.cpp @@ -241,12 +241,12 @@ Id Id::versionedId(const QByteArray &prefix, int major, int minor) QSet<Id> Id::fromStringList(const QStringList &list) { - return QSet<Id>::fromList(Utils::transform(list, &Id::fromString)); + return Utils::transform<QSet<Id>>(list, &Id::fromString); } QStringList Id::toStringList(const QSet<Id> &ids) { - QList<Id> idList = ids.toList(); + QList<Id> idList = Utils::toList(ids); Utils::sort(idList); return Utils::transform(idList, &Id::toString); } diff --git a/src/plugins/coreplugin/jsexpander.cpp b/src/plugins/coreplugin/jsexpander.cpp index 4ee72752e5..22a4562685 100644 --- a/src/plugins/coreplugin/jsexpander.cpp +++ b/src/plugins/coreplugin/jsexpander.cpp @@ -36,6 +36,7 @@ #include <unordered_map> +#if (QT_VERSION < QT_VERSION_CHECK(5, 14, 0)) namespace std { template<> struct hash<QString> { @@ -47,6 +48,7 @@ template<> struct hash<QString> } }; } // namespace std +#endif using ExtensionMap = std::unordered_map<QString, Core::JsExpander::ObjectFactory>; Q_GLOBAL_STATIC(ExtensionMap, globalJsExtensions); diff --git a/src/plugins/coreplugin/locator/locatorsettingspage.cpp b/src/plugins/coreplugin/locator/locatorsettingspage.cpp index d1b2df2183..5e35f2058c 100644 --- a/src/plugins/coreplugin/locator/locatorsettingspage.cpp +++ b/src/plugins/coreplugin/locator/locatorsettingspage.cpp @@ -31,6 +31,8 @@ #include "locatorconstants.h" #include <coreplugin/coreconstants.h> + +#include <utils/algorithm.h> #include <utils/categorysortfiltermodel.h> #include <utils/headerviewstretcher.h> #include <utils/qtcassert.h> @@ -287,7 +289,7 @@ void LocatorSettingsPage::initializeModel() ILocatorFilter::msgIncludeByDefaultToolTip() }); m_model->clear(); - QSet<ILocatorFilter *> customFilterSet = m_customFilters.toSet(); + QSet<ILocatorFilter *> customFilterSet = Utils::toSet(m_customFilters); auto builtIn = new CategoryItem(tr("Built-in"), 0/*order*/); for (ILocatorFilter *filter : qAsConst(m_filters)) if (!filter->isHidden() && !customFilterSet.contains(filter)) diff --git a/src/plugins/cppeditor/cppeditorwidget.cpp b/src/plugins/cppeditor/cppeditorwidget.cpp index e55ac8a665..6877497884 100644 --- a/src/plugins/cppeditor/cppeditorwidget.cpp +++ b/src/plugins/cppeditor/cppeditorwidget.cpp @@ -382,7 +382,7 @@ static void onReplaceUsagesClicked(const QString &text, const QStringList fileNames = TextEditor::BaseFileFind::replaceAll(text, items, preserveCase); if (!fileNames.isEmpty()) { - modelManager->updateSourceFiles(fileNames.toSet()); + modelManager->updateSourceFiles(Utils::toSet(fileNames)); SearchResultWindow::instance()->hide(); } } diff --git a/src/plugins/cppeditor/cppinsertvirtualmethods.cpp b/src/plugins/cppeditor/cppinsertvirtualmethods.cpp index 748c48cf0b..1f2650ac63 100644 --- a/src/plugins/cppeditor/cppinsertvirtualmethods.cpp +++ b/src/plugins/cppeditor/cppinsertvirtualmethods.cpp @@ -36,6 +36,8 @@ #include <cplusplus/CppRewriter.h> #include <cplusplus/Overview.h> + +#include <utils/algorithm.h> #include <utils/changeset.h> #include <utils/qtcassert.h> #include <utils/utilsicons.h> @@ -1086,11 +1088,11 @@ void InsertVirtualMethodsDialog::saveSettings() m_settings->overrideReplacementIndex = m_overrideReplacementComboBox->currentIndex(); if (m_overrideReplacementComboBox && m_overrideReplacementComboBox->isEnabled()) m_settings->overrideReplacement = m_overrideReplacementComboBox->currentText().trimmed(); - QSet<QString> addedReplacements = m_availableOverrideReplacements.toSet(); + QSet<QString> addedReplacements = Utils::toSet(m_availableOverrideReplacements); addedReplacements.insert(m_settings->overrideReplacement); - addedReplacements.subtract(defaultOverrideReplacements().toSet()); + addedReplacements.subtract(Utils::toSet(defaultOverrideReplacements())); m_settings->userAddedOverrideReplacements = - sortedAndTrimmedStringListWithoutEmptyElements(addedReplacements.toList()); + sortedAndTrimmedStringListWithoutEmptyElements(Utils::toList(addedReplacements)); m_settings->write(); } diff --git a/src/plugins/cpptools/builtineditordocumentparser.cpp b/src/plugins/cpptools/builtineditordocumentparser.cpp index a8f44e1e0c..4af8cb9028 100644 --- a/src/plugins/cpptools/builtineditordocumentparser.cpp +++ b/src/plugins/cpptools/builtineditordocumentparser.cpp @@ -29,6 +29,7 @@ #include <projectexplorer/projectmacro.h> #include <projectexplorer/projectexplorerconstants.h> +#include <utils/algorithm.h> #include <utils/qtcassert.h> using namespace CPlusPlus; @@ -269,7 +270,7 @@ void BuiltinEditorDocumentParser::addFileAndDependencies(Snapshot *snapshot, toRemove->insert(fileName); if (fileName != Utils::FilePath::fromString(filePath())) { Utils::FilePathList deps = snapshot->filesDependingOn(fileName); - toRemove->unite(QSet<Utils::FilePath>::fromList(deps)); + toRemove->unite(Utils::toSet(deps)); } } diff --git a/src/plugins/cpptools/builtinindexingsupport.cpp b/src/plugins/cpptools/builtinindexingsupport.cpp index 3677cefc29..484c3adcd5 100644 --- a/src/plugins/cpptools/builtinindexingsupport.cpp +++ b/src/plugins/cpptools/builtinindexingsupport.cpp @@ -197,7 +197,7 @@ void index(QFutureInterface<void> &indexingFuture, const int sourceCount = sources.size(); QStringList files = sources + headers; - sourceProcessor->setTodo(files.toSet()); + sourceProcessor->setTodo(Utils::toSet(files)); const QString conf = CppModelManager::configurationFileName(); bool processingHeaders = false; diff --git a/src/plugins/cpptools/clangdiagnosticconfigswidget.cpp b/src/plugins/cpptools/clangdiagnosticconfigswidget.cpp index 01164bfb1a..58589a5308 100644 --- a/src/plugins/cpptools/clangdiagnosticconfigswidget.cpp +++ b/src/plugins/cpptools/clangdiagnosticconfigswidget.cpp @@ -381,7 +381,7 @@ private: levelNode->childDirectories.append(checkNode); - m_topics.unite(check.topics.toSet()); + m_topics.unite(Utils::toSet(check.topics)); } } @@ -1003,7 +1003,7 @@ void ClangDiagnosticConfigsWidget::setupTabs() setupTreeView(m_clazyChecks->checksView, m_clazySortFilterProxyModel, 2); m_clazyChecks->checksView->setSortingEnabled(true); m_clazyChecks->checksView->sortByColumn(0, Qt::AscendingOrder); - auto topicsModel = new QStringListModel(m_clazyTreeModel->topics().toList(), this); + auto topicsModel = new QStringListModel(Utils::toList(m_clazyTreeModel->topics()), this); topicsModel->sort(0); m_clazyChecks->topicsView->setModel(topicsModel); connect(m_clazyChecks->topicsResetButton, &QPushButton::clicked, [this](){ diff --git a/src/plugins/cpptools/cppcompletion_test.cpp b/src/plugins/cpptools/cppcompletion_test.cpp index b8dd817835..b8ba85fc15 100644 --- a/src/plugins/cpptools/cppcompletion_test.cpp +++ b/src/plugins/cpptools/cppcompletion_test.cpp @@ -388,7 +388,7 @@ void CppToolsPlugin::test_global_completion() QVERIFY(test.succeededSoFar()); const QStringList completions = test.getCompletions(); QVERIFY(isProbablyGlobalCompletion(completions)); - QVERIFY(completions.toSet().contains(requiredCompletionItems.toSet())); + QVERIFY(Utils::toSet(completions).contains(Utils::toSet(requiredCompletionItems))); } void CppToolsPlugin::test_doxygen_tag_completion_data() diff --git a/src/plugins/cpptools/cppfindreferences.cpp b/src/plugins/cpptools/cppfindreferences.cpp index e277edeb4f..f5c4405acd 100644 --- a/src/plugins/cpptools/cppfindreferences.cpp +++ b/src/plugins/cpptools/cppfindreferences.cpp @@ -402,7 +402,7 @@ void CppFindReferences::onReplaceButtonClicked(const QString &text, { const QStringList fileNames = TextEditor::BaseFileFind::replaceAll(text, items, preserveCase); if (!fileNames.isEmpty()) { - m_modelManager->updateSourceFiles(fileNames.toSet()); + m_modelManager->updateSourceFiles(Utils::toSet(fileNames)); SearchResultWindow::instance()->hide(); } diff --git a/src/plugins/cpptools/cppmodelmanager.cpp b/src/plugins/cpptools/cppmodelmanager.cpp index c82355b31b..ea083c8eb6 100644 --- a/src/plugins/cpptools/cppmodelmanager.cpp +++ b/src/plugins/cpptools/cppmodelmanager.cpp @@ -479,7 +479,7 @@ void CppModelManager::initCppTools() this, &CppModelManager::updateModifiedSourceFiles); connect(Core::DocumentManager::instance(), &Core::DocumentManager::filesChangedInternally, [this](const QStringList &files) { - updateSourceFiles(files.toSet()); + updateSourceFiles(Utils::toSet(files)); }); connect(this, &CppModelManager::documentUpdated, @@ -925,7 +925,7 @@ public: { QSet<QString> removed = projectPartIds(m_old.projectParts()); removed.subtract(projectPartIds(m_new.projectParts())); - return removed.toList(); + return Utils::toList(removed); } /// Returns a list of common files that have a changed timestamp. @@ -1020,7 +1020,7 @@ void CppModelManager::updateCppEditorDocuments(bool projectsUpdated) const // Mark invisible documents dirty QSet<Core::IDocument *> invisibleCppEditorDocuments - = Core::DocumentModel::openedDocuments().toSet(); + = Utils::toSet(Core::DocumentModel::openedDocuments()); invisibleCppEditorDocuments.subtract(visibleCppEditorDocuments); foreach (Core::IDocument *document, invisibleCppEditorDocuments) { const QString filePath = document->filePath().toString(); @@ -1085,7 +1085,7 @@ QFuture<void> CppModelManager::updateProjectInfo(QFutureInterface<void> &futureI const QSet<QString> removedFiles = comparer.removedFiles(); if (!removedFiles.isEmpty()) { filesRemoved = true; - emit aboutToRemoveFiles(removedFiles.toList()); + emit aboutToRemoveFiles(Utils::toList(removedFiles)); removeFilesFromSnapshot(removedFiles); } } @@ -1150,9 +1150,8 @@ QList<ProjectPart::Ptr> CppModelManager::projectPartFromDependencies( const Utils::FilePathList deps = snapshot().filesDependingOn(fileName); QMutexLocker locker(&d->m_projectMutex); - foreach (const Utils::FilePath &dep, deps) { - parts.unite(QSet<ProjectPart::Ptr>::fromList(d->m_fileToProjectParts.value(dep))); - } + for (const Utils::FilePath &dep : deps) + parts.unite(Utils::toSet(d->m_fileToProjectParts.value(dep))); return parts.values(); } @@ -1218,10 +1217,10 @@ void CppModelManager::delayedGC() static QStringList removedProjectParts(const QStringList &before, const QStringList &after) { - QSet<QString> b = before.toSet(); - b.subtract(after.toSet()); + QSet<QString> b = Utils::toSet(before); + b.subtract(Utils::toSet(after)); - return b.toList(); + return Utils::toList(b); } void CppModelManager::onAboutToRemoveProject(ProjectExplorer::Project *project) diff --git a/src/plugins/cpptools/cppmodelmanager_test.cpp b/src/plugins/cpptools/cppmodelmanager_test.cpp index ceab10028e..02586943da 100644 --- a/src/plugins/cpptools/cppmodelmanager_test.cpp +++ b/src/plugins/cpptools/cppmodelmanager_test.cpp @@ -568,7 +568,7 @@ void CppToolsPlugin::test_modelmanager_snapshot_after_two_projects() {"foo.h", "foo.cpp", "main.cpp"}); refreshedFiles = helper.updateProjectInfo(project1.projectInfo); - QCOMPARE(refreshedFiles, project1.projectFiles.toSet()); + QCOMPARE(refreshedFiles, Utils::toSet(project1.projectFiles)); const int snapshotSizeAfterProject1 = mm->snapshot().size(); foreach (const QString &file, project1.projectFiles) @@ -580,7 +580,7 @@ void CppToolsPlugin::test_modelmanager_snapshot_after_two_projects() {"bar.h", "bar.cpp", "main.cpp"}); refreshedFiles = helper.updateProjectInfo(project2.projectInfo); - QCOMPARE(refreshedFiles, project2.projectFiles.toSet()); + QCOMPARE(refreshedFiles, Utils::toSet(project2.projectFiles)); const int snapshotSizeAfterProject2 = mm->snapshot().size(); QVERIFY(snapshotSizeAfterProject2 > snapshotSizeAfterProject1); diff --git a/src/plugins/cpptools/symbolsfindfilter.cpp b/src/plugins/cpptools/symbolsfindfilter.cpp index 93f4643587..404a4209a6 100644 --- a/src/plugins/cpptools/symbolsfindfilter.cpp +++ b/src/plugins/cpptools/symbolsfindfilter.cpp @@ -129,7 +129,7 @@ void SymbolsFindFilter::startSearch(SearchResult *search) QSet<QString> projectFileNames; if (parameters.scope == SymbolSearcher::SearchProjectsOnly) { for (ProjectExplorer::Project *project : ProjectExplorer::SessionManager::projects()) - projectFileNames += Utils::transform(project->files(ProjectExplorer::Project::AllFiles), &Utils::FilePath::toString).toSet(); + projectFileNames += Utils::transform<QSet>(project->files(ProjectExplorer::Project::AllFiles), &Utils::FilePath::toString); } auto watcher = new QFutureWatcher<SearchResultItem>; diff --git a/src/plugins/debugger/breakhandler.cpp b/src/plugins/debugger/breakhandler.cpp index 2fd197c618..ec8c062b04 100644 --- a/src/plugins/debugger/breakhandler.cpp +++ b/src/plugins/debugger/breakhandler.cpp @@ -2439,7 +2439,7 @@ GlobalBreakpoints BreakpointManager::findBreakpointsByIndex(const QList<QModelIn if (GlobalBreakpoint gbp = findBreakpointByIndex(index)) items.insert(gbp); } - return items.toList(); + return Utils::toList(items); } GlobalBreakpoint BreakpointManager::createBreakpoint(const BreakpointParameters ¶ms) diff --git a/src/plugins/debugger/debuggermainwindow.cpp b/src/plugins/debugger/debuggermainwindow.cpp index 82bb009cc2..561c9e6e95 100644 --- a/src/plugins/debugger/debuggermainwindow.cpp +++ b/src/plugins/debugger/debuggermainwindow.cpp @@ -506,7 +506,7 @@ void DebuggerMainWindow::savePersistentSettings() QSettings *settings = ICore::settings(); settings->beginGroup(MAINWINDOW_KEY); - settings->setValue(CHANGED_DOCK_KEY, QStringList(changedDocks.toList())); + settings->setValue(CHANGED_DOCK_KEY, QStringList(Utils::toList(changedDocks))); settings->setValue(STATE_KEY, states); settings->setValue(AUTOHIDE_TITLEBARS_KEY, theMainWindow->autoHideTitleBars()); settings->setValue(SHOW_CENTRALWIDGET_KEY, theMainWindow->isCentralWidgetShown()); diff --git a/src/plugins/debugger/debuggertooltipmanager.cpp b/src/plugins/debugger/debuggertooltipmanager.cpp index 2ad12ff682..611e714abd 100644 --- a/src/plugins/debugger/debuggertooltipmanager.cpp +++ b/src/plugins/debugger/debuggertooltipmanager.cpp @@ -259,13 +259,13 @@ ToolTipWatchItem::ToolTipWatchItem(TreeItem *item) { const QAbstractItemModel *model = item->model(); QModelIndex idx = item->index(); - name = model->data(idx.sibling(idx.row(), 0), Qt::DisplayRole).toString(); - value = model->data(idx.sibling(idx.row(), 1), Qt::DisplayRole).toString(); - type = model->data(idx.sibling(idx.row(), 2), Qt::DisplayRole).toString(); - iname = model->data(idx.sibling(idx.row(), 0), LocalsINameRole).toString(); - valueColor = model->data(idx.sibling(idx.row(), 1), Qt::ForegroundRole).value<QColor>(); + name = model->data(idx.sibling(idx.row(), WatchModelBase::NameColumn), Qt::DisplayRole).toString(); + value = model->data(idx.sibling(idx.row(), WatchModelBase::ValueColumn), Qt::DisplayRole).toString(); + type = model->data(idx.sibling(idx.row(), WatchModelBase::TypeColumn), Qt::DisplayRole).toString(); + iname = model->data(idx.sibling(idx.row(), WatchModelBase::NameColumn), LocalsINameRole).toString(); + valueColor = model->data(idx.sibling(idx.row(), WatchModelBase::ValueColumn), Qt::ForegroundRole).value<QColor>(); expandable = model->hasChildren(idx); - expression = model->data(idx.sibling(idx.row(), 0), Qt::EditRole).toString(); + expression = model->data(idx.sibling(idx.row(), WatchModelBase::NameColumn), Qt::EditRole).toString(); for (TreeItem *child : *item) appendChild(new ToolTipWatchItem(child)); } diff --git a/src/plugins/fakevim/fakevimhandler.cpp b/src/plugins/fakevim/fakevimhandler.cpp index 955f3f6062..adb77c7c0d 100644 --- a/src/plugins/fakevim/fakevimhandler.cpp +++ b/src/plugins/fakevim/fakevimhandler.cpp @@ -4139,6 +4139,8 @@ EventResult FakeVimHandler::Private::handleCommandMode(const Input &input) // Process input for a sub-mode. if (input.isEscape()) { handled = handleEscape(); + } else if (m_wasReadOnly) { + return EventUnhandled; } else if (g.subsubmode != NoSubSubMode) { handled = handleCommandSubSubMode(input); } else if (g.submode == NoSubMode) { diff --git a/src/plugins/git/branchmodel.cpp b/src/plugins/git/branchmodel.cpp index bf74f7b32c..8af16f80ee 100644 --- a/src/plugins/git/branchmodel.cpp +++ b/src/plugins/git/branchmodel.cpp @@ -602,15 +602,15 @@ void BranchModel::removeTag(const QModelIndex &idx) removeNode(idx); } -void BranchModel::checkoutBranch(const QModelIndex &idx) +VcsCommand *BranchModel::checkoutBranch(const QModelIndex &idx) { QString branch = fullName(idx, !isLocal(idx)); if (branch.isEmpty()) - return; + return nullptr; // No StashGuard since this function for now is only used with clean working dir. // If it is ever used from another place, please add StashGuard here - d->client->checkout(d->workingDirectory, branch, GitClient::StashMode::NoStash); + return d->client->checkout(d->workingDirectory, branch, GitClient::StashMode::NoStash); } bool BranchModel::branchIsMerged(const QModelIndex &idx) diff --git a/src/plugins/git/branchmodel.h b/src/plugins/git/branchmodel.h index 5c163801fd..2a0de65bbe 100644 --- a/src/plugins/git/branchmodel.h +++ b/src/plugins/git/branchmodel.h @@ -30,6 +30,8 @@ #include <QAbstractListModel> #include <QVariant> +namespace VcsBase { class VcsCommand; } + namespace Git { namespace Internal { @@ -78,7 +80,7 @@ public: void removeBranch(const QModelIndex &idx); void removeTag(const QModelIndex &idx); - void checkoutBranch(const QModelIndex &idx); + VcsBase::VcsCommand *checkoutBranch(const QModelIndex &idx); bool branchIsMerged(const QModelIndex &idx); QModelIndex addBranch(const QString &name, bool track, const QModelIndex &trackedBranch); void setRemoteTracking(const QModelIndex &trackingIndex); diff --git a/src/plugins/git/branchview.cpp b/src/plugins/git/branchview.cpp index 21f9c63e14..686e3f796a 100644 --- a/src/plugins/git/branchview.cpp +++ b/src/plugins/git/branchview.cpp @@ -41,6 +41,7 @@ #include <utils/navigationtreeview.h> #include <utils/qtcassert.h> #include <utils/utilsicons.h> +#include <vcsbase/vcscommand.h> #include <vcsbase/vcsoutputwindow.h> #include <QDir> @@ -382,21 +383,28 @@ bool BranchView::checkout() return false; } - m_model->checkoutBranch(selected); - - QString stashName; - client->synchronousStashList(m_repository, &stashes); - for (const Stash &stash : qAsConst(stashes)) { - if (stash.message.startsWith(popMessageStart)) { - stashName = stash.name; - break; - } + VcsBase::VcsCommand *command = m_model->checkoutBranch(selected); + const bool moveChanges = branchCheckoutDialog.moveLocalChangesToNextBranch(); + const bool popStash = branchCheckoutDialog.popStashOfNextBranch(); + if (command && (moveChanges || popStash)) { + connect(command, &VcsBase::VcsCommand::finished, + this, [this, client, popMessageStart, moveChanges, popStash] { + if (moveChanges) { + client->endStashScope(m_repository); + } else if (popStash) { + QList<Stash> stashes; + QString stashName; + client->synchronousStashList(m_repository, &stashes); + for (const Stash &stash : qAsConst(stashes)) { + if (stash.message.startsWith(popMessageStart)) { + stashName = stash.name; + break; + } + } + client->synchronousStashRestore(m_repository, stashName, true); + } + }); } - - if (branchCheckoutDialog.moveLocalChangesToNextBranch()) - client->endStashScope(m_repository); - else if (branchCheckoutDialog.popStashOfNextBranch()) - client->synchronousStashRestore(m_repository, stashName, true); } if (QTC_GUARD(m_branchView)) diff --git a/src/plugins/git/gitclient.cpp b/src/plugins/git/gitclient.cpp index 9ddcdd77e3..c57a291ac1 100644 --- a/src/plugins/git/gitclient.cpp +++ b/src/plugins/git/gitclient.cpp @@ -1163,11 +1163,11 @@ VcsBaseEditorWidget *GitClient::annotate( return editor; } -void GitClient::checkout(const QString &workingDirectory, const QString &ref, - StashMode stashMode) +VcsCommand *GitClient::checkout(const QString &workingDirectory, const QString &ref, + StashMode stashMode) { if (stashMode == StashMode::TryStash && !beginStashScope(workingDirectory, "Checkout")) - return; + return nullptr; QStringList arguments = setupCheckoutArguments(workingDirectory, ref); VcsCommand *command = vcsExec( workingDirectory, arguments, nullptr, true, @@ -1179,6 +1179,7 @@ void GitClient::checkout(const QString &workingDirectory, const QString &ref, if (success) updateSubmodulesIfNeeded(workingDirectory, true); }); + return command; } /* method used to setup arguments for checkout, in case user wants to create local branch */ @@ -2848,9 +2849,9 @@ GitClient::RevertResult GitClient::revertI(QStringList files, QStringList stagedFiles = allStagedFiles; QStringList unstagedFiles = allUnstagedFiles; if (!isDirectory) { - const QSet<QString> filesSet = files.toSet(); - stagedFiles = allStagedFiles.toSet().intersect(filesSet).toList(); - unstagedFiles = allUnstagedFiles.toSet().intersect(filesSet).toList(); + const QSet<QString> filesSet = Utils::toSet(files); + stagedFiles = Utils::toList(Utils::toSet(allStagedFiles).intersect(filesSet)); + unstagedFiles = Utils::toList(Utils::toSet(allUnstagedFiles).intersect(filesSet)); } if ((!revertStaging || stagedFiles.empty()) && unstagedFiles.empty()) return RevertUnchanged; @@ -2933,7 +2934,7 @@ void GitClient::pull(const QString &workingDirectory, bool rebase) abortCommand = "merge"; } - VcsCommand *command = vcsExecAbortable(workingDirectory, arguments, rebase); + VcsCommand *command = vcsExecAbortable(workingDirectory, arguments, rebase, abortCommand); connect(command, &VcsCommand::success, this, [this, workingDirectory] { updateSubmodulesIfNeeded(workingDirectory, true); }, Qt::QueuedConnection); @@ -3135,11 +3136,13 @@ void GitClient::revert(const QString &workingDirectory, const QString &argument) // Stashing is handled prior to this call. VcsCommand *GitClient::vcsExecAbortable(const QString &workingDirectory, const QStringList &arguments, - bool isRebase) + bool isRebase, + QString abortCommand) { QTC_ASSERT(!arguments.isEmpty(), return nullptr); - QString abortCommand = arguments.at(0); + if (abortCommand.isEmpty()) + abortCommand = arguments.at(0); VcsCommand *command = createCommand(workingDirectory, nullptr, VcsWindowOutputBind); command->setCookie(workingDirectory); command->addFlags(VcsCommand::SshPasswordPrompt diff --git a/src/plugins/git/gitclient.h b/src/plugins/git/gitclient.h index 2c67f87d96..c5e9a0df4f 100644 --- a/src/plugins/git/gitclient.h +++ b/src/plugins/git/gitclient.h @@ -126,7 +126,8 @@ public: VcsBase::VcsCommand *vcsExecAbortable(const QString &workingDirectory, const QStringList &arguments, - bool isRebase = false); + bool isRebase = false, + QString abortCommand = QString()); QString findRepositoryForDirectory(const QString &directory) const; QString findGitDirForRepository(const QString &repositoryDir) const; @@ -174,8 +175,8 @@ public: QString revision = QString(), QString *errorMessage = nullptr, bool revertStaging = true); enum class StashMode { NoStash, TryStash }; - void checkout(const QString &workingDirectory, const QString &ref, - StashMode stashMode = StashMode::TryStash); + VcsBase::VcsCommand *checkout(const QString &workingDirectory, const QString &ref, + StashMode stashMode = StashMode::TryStash); QStringList setupCheckoutArguments(const QString &workingDirectory, const QString &ref); void updateSubmodulesIfNeeded(const QString &workingDirectory, bool prompt); diff --git a/src/plugins/help/docsettingspage.cpp b/src/plugins/help/docsettingspage.cpp index 51a8a7f330..36b9665e04 100644 --- a/src/plugins/help/docsettingspage.cpp +++ b/src/plugins/help/docsettingspage.cpp @@ -210,7 +210,7 @@ void DocSettingsPage::addDocumentation() // file with the same namespace but a different path, we need to unregister the namespace before // we can register the new one. Help engine allows just one registered namespace. if (m_filesToUnregister.contains(nameSpace)) { - QSet<QString> values = m_filesToUnregister.values(nameSpace).toSet(); + QSet<QString> values = Utils::toSet(m_filesToUnregister.values(nameSpace)); values.remove(filePath); m_filesToUnregister.remove(nameSpace); foreach (const QString &value, values) diff --git a/src/plugins/help/filtersettingspage.cpp b/src/plugins/help/filtersettingspage.cpp index 83d0d365f7..cfd184dfc9 100644 --- a/src/plugins/help/filtersettingspage.cpp +++ b/src/plugins/help/filtersettingspage.cpp @@ -32,6 +32,8 @@ #include <coreplugin/helpmanager.h> +#include <utils/algorithm.h> + #include <QCoreApplication> #include <QFileDialog> #include <QMessageBox> @@ -99,7 +101,7 @@ void FilterSettingsPage::updateFilterPage() QSet<QString> attributes; filters = HelpManager::filters(); for (it = filters.constBegin(); it != filters.constEnd(); ++it) - attributes += it.value().toSet(); + attributes += Utils::toSet(it.value()); foreach (const QString &attribute, attributes) new QTreeWidgetItem(m_ui.attributeWidget, QStringList(attribute)); diff --git a/src/plugins/help/helpmanager.cpp b/src/plugins/help/helpmanager.cpp index 68bedb5779..d6dfef6b20 100644 --- a/src/plugins/help/helpmanager.cpp +++ b/src/plugins/help/helpmanager.cpp @@ -372,12 +372,12 @@ void HelpManager::setupHelpManager() d->cleanUpDocumentation(); if (!d->m_nameSpacesToUnregister.isEmpty()) { - m_instance->unregisterDocumentation(d->m_nameSpacesToUnregister.toList()); + m_instance->unregisterDocumentation(Utils::toList(d->m_nameSpacesToUnregister)); d->m_nameSpacesToUnregister.clear(); } if (!d->m_filesToRegister.isEmpty()) { - m_instance->registerDocumentation(d->m_filesToRegister.toList()); + m_instance->registerDocumentation(Utils::toList(d->m_filesToRegister)); d->m_filesToRegister.clear(); } @@ -432,13 +432,13 @@ const QStringList HelpManagerPrivate::documentationFromInstaller() void HelpManagerPrivate::readSettings() { - m_userRegisteredFiles = ICore::settings()->value(QLatin1String(kUserDocumentationKey)) - .toStringList().toSet(); + m_userRegisteredFiles = Utils::toSet(ICore::settings()->value(QLatin1String(kUserDocumentationKey)) + .toStringList()); } void HelpManagerPrivate::writeSettings() { - const QStringList list = m_userRegisteredFiles.toList(); + const QStringList list = Utils::toList(m_userRegisteredFiles); ICore::settings()->setValue(QLatin1String(kUserDocumentationKey), list); } diff --git a/src/plugins/ios/iosconfigurations.cpp b/src/plugins/ios/iosconfigurations.cpp index e91304d272..909a81e25a 100644 --- a/src/plugins/ios/iosconfigurations.cpp +++ b/src/plugins/ios/iosconfigurations.cpp @@ -167,11 +167,11 @@ static QHash<XcodePlatform::ToolchainTarget, ToolChainPair> findToolChains(const static QSet<Kit *> existingAutoDetectedIosKits() { - return Utils::filtered(KitManager::kits(), [](Kit *kit) -> bool { + return Utils::toSet(Utils::filtered(KitManager::kits(), [](Kit *kit) -> bool { Core::Id deviceKind = DeviceTypeKitAspect::deviceTypeId(kit); return kit->isAutoDetected() && (deviceKind == Constants::IOS_DEVICE_TYPE || deviceKind == Constants::IOS_SIMULATOR_TYPE); - }).toSet(); + })); } static void printKits(const QSet<Kit *> &kits) @@ -249,9 +249,9 @@ void IosConfigurations::updateAutomaticKitList() // target -> tool chain const auto targetToolChainHash = findToolChains(platforms); - const auto qtVersions = QtVersionManager::versions([](const BaseQtVersion *v) { + const auto qtVersions = Utils::toSet(QtVersionManager::versions([](const BaseQtVersion *v) { return v->isValid() && v->type() == Constants::IOSQT; - }).toSet(); + })); const DebuggerItem *possibleDebugger = DebuggerItemManager::findByEngineType(LldbEngineType); const QVariant debuggerId = (possibleDebugger ? possibleDebugger->id() : QVariant()); diff --git a/src/plugins/ios/iosprobe.cpp b/src/plugins/ios/iosprobe.cpp index 2564846a2d..384d14e90a 100644 --- a/src/plugins/ios/iosprobe.cpp +++ b/src/plugins/ios/iosprobe.cpp @@ -25,6 +25,7 @@ #include "iosprobe.h" +#include <utils/algorithm.h> #include <utils/synchronousprocess.h> #include <QDir> @@ -120,7 +121,7 @@ void XcodeProbe::setupDefaultToolchains(const QString &devPath) const QFileInfo sdkPathInfo(sdk.path.toString()); if (sdkPathInfo.exists() && sdkPathInfo.isDir()) { clangProfile.sdks.push_back(sdk); - allArchitectures += sdk.architectures.toSet(); + allArchitectures += Utils::toSet(sdk.architectures); } } diff --git a/src/plugins/modeleditor/pxnodecontroller.cpp b/src/plugins/modeleditor/pxnodecontroller.cpp index 86e3b63a5b..c30b1df9e5 100644 --- a/src/plugins/modeleditor/pxnodecontroller.cpp +++ b/src/plugins/modeleditor/pxnodecontroller.cpp @@ -42,6 +42,8 @@ #include "qmt/tasks/diagramscenecontroller.h" #include <projectexplorer/projectnodes.h> + +#include <utils/algorithm.h> #include <utils/qtcassert.h> #include <QAction> @@ -154,7 +156,7 @@ void PxNodeController::addFileSystemEntry(const QString &filePath, int line, int auto menu = new QMenu; menu->addAction(new MenuAction(tr("Add Component %1").arg(elementName), elementName, MenuAction::TYPE_ADD_COMPONENT, menu)); - QStringList classNames = d->classViewController->findClassDeclarations(filePath, line, column).toList(); + QStringList classNames = Utils::toList(d->classViewController->findClassDeclarations(filePath, line, column)); if (!classNames.empty()) { menu->addSeparator(); int index = 0; diff --git a/src/plugins/projectexplorer/deploymentdata.cpp b/src/plugins/projectexplorer/deploymentdata.cpp index 7cdc4a1185..acb8878de6 100644 --- a/src/plugins/projectexplorer/deploymentdata.cpp +++ b/src/plugins/projectexplorer/deploymentdata.cpp @@ -64,7 +64,7 @@ DeployableFile DeploymentData::deployableForLocalFile(const QString &localFilePa bool DeploymentData::operator==(const DeploymentData &other) const { - return m_files.toSet() == other.m_files.toSet() + return Utils::toSet(m_files) == Utils::toSet(other.m_files) && m_localInstallRoot == other.m_localInstallRoot; } diff --git a/src/plugins/projectexplorer/gccparser.cpp b/src/plugins/projectexplorer/gccparser.cpp index fff0606889..d6521cde99 100644 --- a/src/plugins/projectexplorer/gccparser.cpp +++ b/src/plugins/projectexplorer/gccparser.cpp @@ -908,6 +908,115 @@ void ProjectExplorerPlugin::testGccOutputParsers_data() categoryCompile) ) << QString(); + QTest::newRow("GCC 9 output") + << QString("In file included from /usr/include/qt/QtCore/qlocale.h:43,\n" + " from /usr/include/qt/QtCore/qtextstream.h:46,\n" + " from /qtc/src/shared/proparser/proitems.cpp:31:\n" + "/usr/include/qt/QtCore/qvariant.h: In constructor ‘QVariant::QVariant(QVariant&&)’:\n" + "/usr/include/qt/QtCore/qvariant.h:273:25: warning: implicitly-declared ‘constexpr QVariant::Private& QVariant::Private::operator=(const QVariant::Private&)’ is deprecated [-Wdeprecated-copy]\n" + " 273 | { other.d = Private(); }\n" + " | ^\n" + "/usr/include/qt/QtCore/qvariant.h:399:16: note: because ‘QVariant::Private’ has user-provided ‘QVariant::Private::Private(const QVariant::Private&)’\n" + " 399 | inline Private(const Private &other) Q_DECL_NOTHROW\n" + " | ^~~~~~~)\n" + "t.cc: In function ‘int test(const shape&, const shape&)’:\n" + "t.cc:15:4: error: no match for ‘operator+’ (operand types are ‘boxed_value<double>’ and ‘boxed_value<double>’)\n" + " 14 | return (width(s1) * height(s1)\n" + " | ~~~~~~~~~~~~~~~~~~~~~~\n" + " | |\n" + " | boxed_value<[...]>\n" + " 15 | + width(s2) * height(s2));\n" + " | ^ ~~~~~~~~~~~~~~~~~~~~~~\n" + " | |\n" + " | boxed_value<[...]>\n" + "incomplete.c:1:6: error: ‘string’ in namespace ‘std’ does not name a type\n" + " 1 | std::string test(void)\n" + " | ^~~~~~\n" + "incomplete.c:1:1: note: ‘std::string’ is defined in header ‘<string>’; did you forget to ‘#include <string>’?\n" + " +++ |+#include <string>\n" + " 1 | std::string test(void)\n" + "param-type-mismatch.c: In function ‘caller’:\n" + "param-type-mismatch.c:5:24: warning: passing argument 2 of ‘callee’ makes pointer from integer without a cast [-Wint-conversion]\n" + " 5 | return callee(first, second, third);\n" + " | ^~~~~~\n" + " | |\n" + " | int\n" + "param-type-mismatch.c:1:40: note: expected ‘const char *’ but argument is of type ‘int’\n" + " 1 | extern int callee(int one, const char *two, float three);\n" + " | ~~~~~~~~~~~~^~~" + ) + << OutputParserTester::STDERR + << QString() << QString() + << Tasks{Task(Task::Unknown, + "In file included from /usr/include/qt/QtCore/qlocale.h:43,", + Utils::FilePath::fromUserInput("/usr/include/qt/QtCore/qlocale.h"), 43, + categoryCompile), + Task(Task::Unknown, + "from /usr/include/qt/QtCore/qtextstream.h:46,", + Utils::FilePath::fromUserInput("/usr/include/qt/QtCore/qtextstream.h"), 46, + categoryCompile), + Task(Task::Unknown, + "from /qtc/src/shared/proparser/proitems.cpp:31:", + Utils::FilePath::fromUserInput("/qtc/src/shared/proparser/proitems.cpp"), 31, + categoryCompile), + Task(Task::Unknown, + "In constructor ‘QVariant::QVariant(QVariant&&)’:", + Utils::FilePath::fromUserInput("/usr/include/qt/QtCore/qvariant.h"), -1, + categoryCompile), + Task(Task::Warning, + "implicitly-declared ‘constexpr QVariant::Private& QVariant::Private::operator=(const QVariant::Private&)’ is deprecated [-Wdeprecated-copy]\n" + " 273 | { other.d = Private(); }\n" + " | ^", + Utils::FilePath::fromUserInput("/usr/include/qt/QtCore/qvariant.h"), 273, + categoryCompile), + Task(Task::Unknown, + "because ‘QVariant::Private’ has user-provided ‘QVariant::Private::Private(const QVariant::Private&)’\n" + " 399 | inline Private(const Private &other) Q_DECL_NOTHROW\n" + " | ^~~~~~~)", + Utils::FilePath::fromUserInput("/usr/include/qt/QtCore/qvariant.h"), 399, + categoryCompile), + Task(Task::Unknown, + "In function ‘int test(const shape&, const shape&)’:", + Utils::FilePath::fromUserInput("t.cc"), -1, + categoryCompile), + Task(Task::Error, + "no match for ‘operator+’ (operand types are ‘boxed_value<double>’ and ‘boxed_value<double>’)\n" + " 14 | return (width(s1) * height(s1)\n" + " | ~~~~~~~~~~~~~~~~~~~~~~\n" + " | |\n" + " | boxed_value<[...]>\n" + " 15 | + width(s2) * height(s2));\n" + " | ^ ~~~~~~~~~~~~~~~~~~~~~~\n" + " | |\n" + " | boxed_value<[...]>", + Utils::FilePath::fromUserInput("t.cc"), 15, + categoryCompile), + Task(Task::Error, + "‘string’ in namespace ‘std’ does not name a type\n" + " 1 | std::string test(void)\n" + " | ^~~~~~", + Utils::FilePath::fromUserInput("incomplete.c"), 1, categoryCompile), + Task(Task::Unknown, + "‘std::string’ is defined in header ‘<string>’; did you forget to ‘#include <string>’?\n" + " +++ |+#include <string>\n" + " 1 | std::string test(void)", + Utils::FilePath::fromUserInput("incomplete.c"), 1, categoryCompile), + Task(Task::Unknown, + "In function ‘caller’:", + Utils::FilePath::fromUserInput("param-type-mismatch.c"), -1, categoryCompile), + Task(Task::Warning, + "passing argument 2 of ‘callee’ makes pointer from integer without a cast [-Wint-conversion]\n" + " 5 | return callee(first, second, third);\n" + " | ^~~~~~\n" + " | |\n" + " | int", + Utils::FilePath::fromUserInput("param-type-mismatch.c"), 5, categoryCompile), + Task(Task::Unknown, + "expected ‘const char *’ but argument is of type ‘int’\n" + " 1 | extern int callee(int one, const char *two, float three);\n" + " | ~~~~~~~~~~~~^~~", + Utils::FilePath::fromUserInput("param-type-mismatch.c"), 1, categoryCompile)} + << QString(); } void ProjectExplorerPlugin::testGccOutputParsers() diff --git a/src/plugins/projectexplorer/jsonwizard/jsonwizardfilegenerator.cpp b/src/plugins/projectexplorer/jsonwizard/jsonwizardfilegenerator.cpp index a168fea084..c8ae9aa013 100644 --- a/src/plugins/projectexplorer/jsonwizard/jsonwizardfilegenerator.cpp +++ b/src/plugins/projectexplorer/jsonwizard/jsonwizardfilegenerator.cpp @@ -190,8 +190,7 @@ Core::GeneratedFiles JsonWizardFileGenerator::fileList(Utils::MacroExpander *exp std::tie(fileList, dirList) = Utils::partition(concreteFiles, [](const File &f) { return !QFileInfo(f.source).isDir(); }); - const QSet<QString> knownFiles - = QSet<QString>::fromList(Utils::transform(fileList, &File::target)); + const QSet<QString> knownFiles = Utils::transform<QSet>(fileList, &File::target); foreach (const File &dir, dirList) { QDir sourceDir(dir.source); diff --git a/src/plugins/projectexplorer/jsonwizard/jsonwizardgeneratorfactory.cpp b/src/plugins/projectexplorer/jsonwizard/jsonwizardgeneratorfactory.cpp index cf84f8b5e4..ae3e6aaa52 100644 --- a/src/plugins/projectexplorer/jsonwizard/jsonwizardgeneratorfactory.cpp +++ b/src/plugins/projectexplorer/jsonwizard/jsonwizardgeneratorfactory.cpp @@ -215,7 +215,7 @@ JsonWizardGenerator::OverwriteResult JsonWizardGenerator::promptForOverwrite(Jso if (overwriteDialog.exec() != QDialog::Accepted) return OverwriteCanceled; - const QSet<QString> existingFilesToKeep = QSet<QString>::fromList(overwriteDialog.uncheckedFiles()); + const QSet<QString> existingFilesToKeep = Utils::toSet(overwriteDialog.uncheckedFiles()); if (existingFilesToKeep.size() == files->size()) // All exist & all unchecked->Cancel. return OverwriteCanceled; diff --git a/src/plugins/projectexplorer/kit.cpp b/src/plugins/projectexplorer/kit.cpp index 88e2e65ada..bb44b6bec8 100644 --- a/src/plugins/projectexplorer/kit.cpp +++ b/src/plugins/projectexplorer/kit.cpp @@ -228,13 +228,11 @@ Kit *Kit::clone(bool keepName) const void Kit::copyFrom(const Kit *k) { - KitGuard g(this); copyKitCommon(this, k); d->m_autodetected = k->d->m_autodetected; d->m_autoDetectionSource = k->d->m_autoDetectionSource; d->m_unexpandedDisplayName = k->d->m_unexpandedDisplayName; d->m_fileSystemFriendlyName = k->d->m_fileSystemFriendlyName; - d->m_mustNotify = true; } bool Kit::isValid() const diff --git a/src/plugins/projectexplorer/kitinformation.cpp b/src/plugins/projectexplorer/kitinformation.cpp index 562e090806..c091d0d870 100644 --- a/src/plugins/projectexplorer/kitinformation.cpp +++ b/src/plugins/projectexplorer/kitinformation.cpp @@ -226,14 +226,14 @@ public: layout->setContentsMargins(0, 0, 0, 0); layout->setColumnStretch(1, 2); - QList<Core::Id> languageList = ToolChainManager::allLanguages().toList(); + QList<Core::Id> languageList = Utils::toList(ToolChainManager::allLanguages()); Utils::sort(languageList, [](Core::Id l1, Core::Id l2) { return ToolChainManager::displayNameOfLanguageId(l1) < ToolChainManager::displayNameOfLanguageId(l2); }); QTC_ASSERT(!languageList.isEmpty(), return); int row = 0; - foreach (Core::Id l, languageList) { + for (Core::Id l : qAsConst(languageList)) { layout->addWidget(new QLabel(ToolChainManager::displayNameOfLanguageId(l) + ':'), row, 0); auto cb = new QComboBox; cb->setSizePolicy(QSizePolicy::Ignored, cb->sizePolicy().verticalPolicy()); @@ -385,7 +385,7 @@ Tasks ToolChainKitAspect::validate(const Kit *k) const } if (targetAbis.count() != 1) { result << Task(Task::Error, tr("Compilers produce code for different ABIs: %1") - .arg(Utils::transform(targetAbis, &Abi::toString).toList().join(", ")), + .arg(Utils::transform<QList>(targetAbis, &Abi::toString).join(", ")), Utils::FilePath(), -1, Core::Id(Constants::TASK_CATEGORY_BUILDSYSTEM)); } } @@ -606,7 +606,7 @@ QList<ToolChain *> ToolChainKitAspect::toolChains(const Kit *k) const QVariantMap value = k->value(ToolChainKitAspect::id()).toMap(); const QList<ToolChain *> tcList - = Utils::transform(ToolChainManager::allLanguages().toList(), + = Utils::transform<QList>(ToolChainManager::allLanguages(), [&value](Core::Id l) -> ToolChain * { return ToolChainManager::findToolChain(value.value(l.toString()).toByteArray()); }); diff --git a/src/plugins/projectexplorer/projectexplorer.cpp b/src/plugins/projectexplorer/projectexplorer.cpp index 03b19765c7..41f00ea779 100644 --- a/src/plugins/projectexplorer/projectexplorer.cpp +++ b/src/plugins/projectexplorer/projectexplorer.cpp @@ -3502,7 +3502,7 @@ void ProjectExplorerPluginPrivate::addExistingProjects() } if (!failedProjects.empty()) { const QString message = tr("The following subprojects could not be added to project " - "\"%2\":").arg(projectNode->managingProject()->displayName()); + "\"%1\":").arg(projectNode->managingProject()->displayName()); QMessageBox::warning(ICore::mainWindow(), tr("Adding Subproject Failed"), message + "\n " + failedProjects.join("\n ")); return; diff --git a/src/plugins/projectexplorer/selectablefilesmodel.cpp b/src/plugins/projectexplorer/selectablefilesmodel.cpp index 28d6f4ef23..71077cf570 100644 --- a/src/plugins/projectexplorer/selectablefilesmodel.cpp +++ b/src/plugins/projectexplorer/selectablefilesmodel.cpp @@ -55,7 +55,7 @@ SelectableFilesModel::SelectableFilesModel(QObject *parent) : QAbstractItemModel void SelectableFilesModel::setInitialMarkedFiles(const Utils::FilePathList &files) { - m_files = files.toSet(); + m_files = Utils::toSet(files); m_allFiles = files.isEmpty(); } @@ -320,14 +320,14 @@ void SelectableFilesModel::collectPaths(Tree *root, Utils::FilePathList *result) Utils::FilePathList SelectableFilesModel::selectedFiles() const { - Utils::FilePathList result = m_outOfBaseDirFiles.toList(); + Utils::FilePathList result = Utils::toList(m_outOfBaseDirFiles); collectFiles(m_root, &result); return result; } Utils::FilePathList SelectableFilesModel::preservedFiles() const { - return m_outOfBaseDirFiles.toList(); + return Utils::toList(m_outOfBaseDirFiles); } bool SelectableFilesModel::hasCheckedFiles() const diff --git a/src/plugins/projectexplorer/target.cpp b/src/plugins/projectexplorer/target.cpp index 5724985eb7..ae7b563dbd 100644 --- a/src/plugins/projectexplorer/target.cpp +++ b/src/plugins/projectexplorer/target.cpp @@ -347,7 +347,7 @@ DeploymentData Target::deploymentData() const void Target::setApplicationTargets(const QList<BuildTargetInfo> &appTargets) { - if (appTargets.toSet() != d->m_appTargets.toSet()) { + if (Utils::toSet(appTargets) != Utils::toSet(d->m_appTargets)) { d->m_appTargets = appTargets; emit applicationTargetsChanged(); } diff --git a/src/plugins/projectexplorer/targetsettingspanel.cpp b/src/plugins/projectexplorer/targetsettingspanel.cpp index 6831a3d74c..cc6d37413c 100644 --- a/src/plugins/projectexplorer/targetsettingspanel.cpp +++ b/src/plugins/projectexplorer/targetsettingspanel.cpp @@ -95,8 +95,10 @@ protected: void keyPressEvent(QKeyEvent *event) override { - if (m_targetSetupPage && m_targetSetupPage->importLineEditHasFocus()) + if ((m_targetSetupPage && m_targetSetupPage->importLineEditHasFocus()) + || (m_configureButton && !m_configureButton->isEnabled())) { return; + } if (event->key() == Qt::Key_Return || event->key() == Qt::Key_Enter) { event->accept(); if (m_targetSetupPage) diff --git a/src/plugins/projectexplorer/toolchainoptionspage.cpp b/src/plugins/projectexplorer/toolchainoptionspage.cpp index a16c6f216e..7a005b40bb 100644 --- a/src/plugins/projectexplorer/toolchainoptionspage.cpp +++ b/src/plugins/projectexplorer/toolchainoptionspage.cpp @@ -97,7 +97,7 @@ public: } case Qt::ToolTipRole: if (!toolChain->isValid()) - return ToolChainOptionsPage::tr("This toolchain is no longer valid."); + return ToolChainOptionsPage::tr("This toolchain is invalid."); return ToolChainOptionsPage::tr("<nobr><b>ABI:</b> %1").arg( changed ? ToolChainOptionsPage::tr("not up-to-date") : toolChain->targetAbi().toString()); @@ -190,7 +190,7 @@ public: m_addButton = new QPushButton(ToolChainOptionsPage::tr("Add"), this); auto addMenu = new QMenu; foreach (ToolChainFactory *factory, m_factories) { - QList<Core::Id> languages = factory->supportedLanguages().toList(); + QList<Core::Id> languages = Utils::toList(factory->supportedLanguages()); if (languages.isEmpty()) continue; diff --git a/src/plugins/projectexplorer/toolchainsettingsaccessor.cpp b/src/plugins/projectexplorer/toolchainsettingsaccessor.cpp index 1d8ea687b3..64d458e2e5 100644 --- a/src/plugins/projectexplorer/toolchainsettingsaccessor.cpp +++ b/src/plugins/projectexplorer/toolchainsettingsaccessor.cpp @@ -89,7 +89,7 @@ static QList<ToolChain *> makeUniqueByEqual(const QList<ToolChain *> &a) static QList<ToolChain *> makeUniqueByPointerEqual(const QList<ToolChain *> &a) { - return QSet<ToolChain *>::fromList(a).toList(); + return Utils::toList(Utils::toSet(a)); } static QList<ToolChain *> subtractById(const QList<ToolChain *> &a, const QList<ToolChain *> &b) @@ -478,12 +478,12 @@ void ProjectExplorerPlugin::testToolChainMerging() Internal::ToolChainOperations ops = Internal::mergeToolChainLists(system, user, autodetect); - QSet<ToolChain *> expToRegister = QSet<ToolChain *>::fromList(toRegister); - QSet<ToolChain *> expToDemote = QSet<ToolChain *>::fromList(toDemote); + QSet<ToolChain *> expToRegister = Utils::toSet(toRegister); + QSet<ToolChain *> expToDemote = Utils::toSet(toDemote); - QSet<ToolChain *> actToRegister = QSet<ToolChain *>::fromList(ops.toRegister); - QSet<ToolChain *> actToDemote = QSet<ToolChain *>::fromList(ops.toDemote); - QSet<ToolChain *> actToDelete = QSet<ToolChain *>::fromList(ops.toDelete); + QSet<ToolChain *> actToRegister = Utils::toSet(ops.toRegister); + QSet<ToolChain *> actToDemote = Utils::toSet(ops.toDemote); + QSet<ToolChain *> actToDelete = Utils::toSet(ops.toDelete); QCOMPARE(actToRegister.count(), ops.toRegister.count()); // no dups! QCOMPARE(actToDemote.count(), ops.toDemote.count()); // no dups! @@ -499,12 +499,12 @@ void ProjectExplorerPlugin::testToolChainMerging() tmp = actToRegister; tmp.unite(actToDelete); - QCOMPARE(tmp, QSet<ToolChain *>::fromList(system + user + autodetect)); // All input is accounted for + QCOMPARE(tmp, Utils::toSet(system + user + autodetect)); // All input is accounted for QCOMPARE(expToRegister, actToRegister); QCOMPARE(expToDemote, actToDemote); - QCOMPARE(QSet<ToolChain *>::fromList(system + user + autodetect), - QSet<ToolChain *>::fromList(ops.toRegister + ops.toDemote + ops.toDelete)); + QCOMPARE(Utils::toSet(system + user + autodetect), + Utils::toSet(ops.toRegister + ops.toDemote + ops.toDelete)); } } // namespace ProjectExplorer diff --git a/src/plugins/pythoneditor/pythoneditorplugin.cpp b/src/plugins/pythoneditor/pythoneditorplugin.cpp index bae2a90f7b..00f5639eb8 100644 --- a/src/plugins/pythoneditor/pythoneditorplugin.cpp +++ b/src/plugins/pythoneditor/pythoneditorplugin.cpp @@ -384,7 +384,7 @@ static QStringList readLinesJson(const Utils::FilePath &projectFile, for (const auto &file : files_array) visited.insert(file.toString()); - lines.append(visited.toList()); + lines.append(Utils::toList(visited)); } return lines; diff --git a/src/plugins/qmakeprojectmanager/qmakeparsernodes.cpp b/src/plugins/qmakeprojectmanager/qmakeparsernodes.cpp index b9dd48d49e..e562638838 100644 --- a/src/plugins/qmakeprojectmanager/qmakeparsernodes.cpp +++ b/src/plugins/qmakeprojectmanager/qmakeparsernodes.cpp @@ -1914,8 +1914,9 @@ InstallsList QmakeProFile::installsList(const QtSupport::ProFileReader *reader, bool fixInstallPrefix = (installPrefix != devInstallPrefix); foreach (const QString &item, itemList) { - bool active = !reader->values(item + QLatin1String(".CONFIG")) - .contains(QLatin1String("no_default_install")); + const QStringList config = reader->values(item + ".CONFIG"); + const bool active = !config.contains("no_default_install"); + const bool executable = config.contains("executable"); const QString pathVar = item + QLatin1String(".path"); const QStringList &itemPaths = reader->values(pathVar); if (itemPaths.count() != 1) { @@ -1943,7 +1944,7 @@ InstallsList QmakeProFile::installsList(const QtSupport::ProFileReader *reader, } else { const auto &itemFiles = reader->fixifiedValues( item + QLatin1String(".files"), projectDir, buildDir, true); - result.items << InstallsItem(itemPath, itemFiles, active); + result.items << InstallsItem(itemPath, itemFiles, active, executable); } } return result; diff --git a/src/plugins/qmakeprojectmanager/qmakeparsernodes.h b/src/plugins/qmakeprojectmanager/qmakeparsernodes.h index 601400f47b..465f472c07 100644 --- a/src/plugins/qmakeprojectmanager/qmakeparsernodes.h +++ b/src/plugins/qmakeprojectmanager/qmakeparsernodes.h @@ -266,11 +266,12 @@ public: class QMAKEPROJECTMANAGER_EXPORT InstallsItem { public: InstallsItem() = default; - InstallsItem(QString p, QVector<ProFileEvaluator::SourceFile> f, bool a) - : path(p), files(f), active(a) {} + InstallsItem(QString p, QVector<ProFileEvaluator::SourceFile> f, bool a, bool e) + : path(p), files(f), active(a), executable(e) {} QString path; QVector<ProFileEvaluator::SourceFile> files; bool active = false; + bool executable = false; }; class QMAKEPROJECTMANAGER_EXPORT InstallsList { diff --git a/src/plugins/qmakeprojectmanager/qmakeproject.cpp b/src/plugins/qmakeprojectmanager/qmakeproject.cpp index 6f5925b51b..205782b1df 100644 --- a/src/plugins/qmakeprojectmanager/qmakeproject.cpp +++ b/src/plugins/qmakeprojectmanager/qmakeproject.cpp @@ -930,7 +930,7 @@ void CentralizedFolderWatcher::delayedFolderChanged(const QString &folder) QSet<QString> alreadyAdded = m_watcher.directories().toSet(); tmp.subtract(alreadyAdded); if (!tmp.isEmpty()) - m_watcher.addPaths(tmp.toList()); + m_watcher.addPaths(Utils::toList(tmp)); m_recursiveWatchedFolders += tmp; } @@ -1063,8 +1063,10 @@ void QmakeProject::collectData(const QmakeProFile *file, DeploymentData &deploym for (const InstallsItem &item : installsList.items) { if (!item.active) continue; - foreach (const auto &localFile, item.files) - deploymentData.addFile(localFile.fileName, item.path); + for (const auto &localFile : item.files) { + deploymentData.addFile(localFile.fileName, item.path, item.executable + ? DeployableFile::TypeExecutable : DeployableFile::TypeNormal); + } } switch (file->projectType()) { diff --git a/src/plugins/qmldesigner/components/curveeditor/detail/playhead.h b/src/plugins/qmldesigner/components/curveeditor/detail/playhead.h index 28d2a21a5c..3a785624bd 100644 --- a/src/plugins/qmldesigner/components/curveeditor/detail/playhead.h +++ b/src/plugins/qmldesigner/components/curveeditor/detail/playhead.h @@ -65,8 +65,6 @@ private: QRectF m_rect; QTimer m_timer; - - GraphicsView *m_view; }; } // End namespace DesignTools. diff --git a/src/plugins/qmldesigner/components/curveeditor/detail/selector.h b/src/plugins/qmldesigner/components/curveeditor/detail/selector.h index e8f53d9d59..1c955de5be 100644 --- a/src/plugins/qmldesigner/components/curveeditor/detail/selector.h +++ b/src/plugins/qmldesigner/components/curveeditor/detail/selector.h @@ -70,8 +70,6 @@ private: Shortcut m_shortcut; - SelectionMode m_mode = SelectionMode::Undefined; - SelectionTool m_tool = SelectionTool::Rectangle; QPoint m_mouseInit = QPoint(); diff --git a/src/plugins/qmldesigner/components/formeditor/contentnoteditableindicator.cpp b/src/plugins/qmldesigner/components/formeditor/contentnoteditableindicator.cpp index 26c1390217..22e1c86dbc 100644 --- a/src/plugins/qmldesigner/components/formeditor/contentnoteditableindicator.cpp +++ b/src/plugins/qmldesigner/components/formeditor/contentnoteditableindicator.cpp @@ -26,6 +26,8 @@ #include "contentnoteditableindicator.h" #include "nodemetainfo.h" +#include <utils/algorithm.h> + #include <QSet> #include <QPen> @@ -68,9 +70,9 @@ void ContentNotEditableIndicator::setItems(const QList<FormEditorItem*> &itemLis void ContentNotEditableIndicator::updateItems(const QList<FormEditorItem *> &itemList) { QSet<FormEditorItem*> affectedFormEditorItemItems; - affectedFormEditorItemItems.unite(itemList.toSet()); + affectedFormEditorItemItems.unite(Utils::toSet(itemList)); foreach (FormEditorItem *formEditorItem, itemList) - affectedFormEditorItemItems.unite(formEditorItem->offspringFormEditorItems().toSet()); + affectedFormEditorItemItems.unite(Utils::toSet(formEditorItem->offspringFormEditorItems())); foreach (const EntryPair &entryPair, m_entryList) { foreach (FormEditorItem *formEditorItem, affectedFormEditorItemItems) { diff --git a/src/plugins/qmldesigner/components/formeditor/rubberbandselectionmanipulator.cpp b/src/plugins/qmldesigner/components/formeditor/rubberbandselectionmanipulator.cpp index 05d13e29e7..ccd5813a9f 100644 --- a/src/plugins/qmldesigner/components/formeditor/rubberbandselectionmanipulator.cpp +++ b/src/plugins/qmldesigner/components/formeditor/rubberbandselectionmanipulator.cpp @@ -27,6 +27,8 @@ #include "formeditorscene.h" +#include <utils/algorithm.h> + namespace QmlDesigner { RubberBandSelectionManipulator::RubberBandSelectionManipulator(LayerItem *layerItem, FormEditorView *editorView) @@ -125,9 +127,9 @@ void RubberBandSelectionManipulator::select(SelectionType selectionType) } break; case RemoveFromSelection: { - QSet<QmlItemNode> oldSelectionSet(m_oldSelectionList.toSet()); - QSet<QmlItemNode> newSelectionSet(newNodeList.toSet()); - nodeList.append(oldSelectionSet.subtract(newSelectionSet).toList()); + QSet<QmlItemNode> oldSelectionSet = Utils::toSet(m_oldSelectionList); + const QSet<QmlItemNode> newSelectionSet = Utils::toSet(newNodeList); + nodeList.append(Utils::toList(oldSelectionSet.subtract(newSelectionSet))); } } diff --git a/src/plugins/qmldesigner/components/navigator/navigatortreemodel.cpp b/src/plugins/qmldesigner/components/navigator/navigatortreemodel.cpp index 8c89acb7c8..08d2454bb1 100644 --- a/src/plugins/qmldesigner/components/navigator/navigatortreemodel.cpp +++ b/src/plugins/qmldesigner/components/navigator/navigatortreemodel.cpp @@ -634,7 +634,7 @@ static QList<ModelNode> collectParents(const QList<ModelNode> &modelNodes) } } - return parents.toList(); + return Utils::toList(parents); } QList<QPersistentModelIndex> NavigatorTreeModel::nodesToPersistentIndex(const QList<ModelNode> &modelNodes) diff --git a/src/plugins/qmldesigner/components/propertyeditor/propertyeditorcontextobject.cpp b/src/plugins/qmldesigner/components/propertyeditor/propertyeditorcontextobject.cpp index 8fdab5a821..d553ccca22 100644 --- a/src/plugins/qmldesigner/components/propertyeditor/propertyeditorcontextobject.cpp +++ b/src/plugins/qmldesigner/components/propertyeditor/propertyeditorcontextobject.cpp @@ -35,6 +35,8 @@ #include <utils/algorithm.h> #include <utils/qtcassert.h> +#include <QApplication> +#include <QCursor> #include <QQmlContext> static uchar fromHex(const uchar c, const uchar c2) @@ -386,4 +388,22 @@ void PropertyEditorContextObject::setHasAliasExport(bool hasAliasExport) emit hasAliasExportChanged(); } +void PropertyEditorContextObject::hideCursor() +{ + if (QApplication::overrideCursor()) + return; + + QApplication::setOverrideCursor(QCursor(Qt::BlankCursor)); + m_lastPos = QCursor::pos(); +} + +void PropertyEditorContextObject::restoreCursor() +{ + if (!QApplication::overrideCursor()) + return; + + QCursor::setPos(m_lastPos); + QApplication::restoreOverrideCursor(); +} + } //QmlDesigner diff --git a/src/plugins/qmldesigner/components/propertyeditor/propertyeditorcontextobject.h b/src/plugins/qmldesigner/components/propertyeditor/propertyeditorcontextobject.h index 42f4951a58..150800feba 100644 --- a/src/plugins/qmldesigner/components/propertyeditor/propertyeditorcontextobject.h +++ b/src/plugins/qmldesigner/components/propertyeditor/propertyeditorcontextobject.h @@ -32,6 +32,7 @@ #include <QQmlPropertyMap> #include <QQmlComponent> #include <QColor> +#include <QPoint> namespace QmlDesigner { @@ -85,6 +86,9 @@ public: Q_INVOKABLE void changeTypeName(const QString &typeName); Q_INVOKABLE void insertKeyframe(const QString &propertyName); + Q_INVOKABLE void hideCursor(); + Q_INVOKABLE void restoreCursor(); + int majorVersion() const; int majorQtQuickVersion() const; int minorQtQuickVersion() const; @@ -157,6 +161,8 @@ private: QQmlComponent *m_qmlComponent; QQmlContext *m_qmlContext; + QPoint m_lastPos; + Model *m_model = nullptr; bool m_aliasExport = false; diff --git a/src/plugins/qmldesigner/components/propertyeditor/propertyeditorqmlbackend.cpp b/src/plugins/qmldesigner/components/propertyeditor/propertyeditorqmlbackend.cpp index 12f12ed2bc..ae47586641 100644 --- a/src/plugins/qmldesigner/components/propertyeditor/propertyeditorqmlbackend.cpp +++ b/src/plugins/qmldesigner/components/propertyeditor/propertyeditorqmlbackend.cpp @@ -401,6 +401,39 @@ QString PropertyEditorQmlBackend::propertyEditorResourcesPath() { return Core::ICore::resourcePath() + QStringLiteral("/qmldesigner/propertyEditorQmlSources"); } +inline bool dotPropertyHeuristic(const QmlObjectNode &node, const NodeMetaInfo &type, const PropertyName &name) +{ + if (!name.contains(".")) + return true; + + if (name.count('.') > 1) + return false; + + QList<QByteArray> list =name.split('.'); + const PropertyName parentProperty = list.first(); + const PropertyName itemProperty = list.last(); + + TypeName typeName = type.propertyTypeName(parentProperty); + + NodeMetaInfo itemInfo = node.view()->model()->metaInfo("QtQuick.Item"); + NodeMetaInfo textInfo = node.view()->model()->metaInfo("QtQuick.Text"); + NodeMetaInfo rectangleInfo = node.view()->model()->metaInfo("QtQuick.Rectangle"); + + if (itemInfo.hasProperty(itemProperty)) + return false; + + if (typeName == "font") + return false; + + if (textInfo.isSubclassOf(typeName)) + return false; + + if (rectangleInfo.isSubclassOf(typeName)) + return false; + + return true; +} + QString PropertyEditorQmlBackend::templateGeneration(const NodeMetaInfo &type, const NodeMetaInfo &superType, const QmlObjectNode &node) @@ -461,9 +494,9 @@ QString PropertyEditorQmlBackend::templateGeneration(const NodeMetaInfo &type, auto nodes = templateConfiguration()->children(); - if (!superType.hasProperty(name) && type.propertyIsWritable(name) && !name.contains(".")) { + if (!superType.hasProperty(name) && type.propertyIsWritable(name) && dotPropertyHeuristic(node, type, name)) { - foreach (const QmlJS::SimpleReaderNode::Ptr &node, nodes) + for (const QmlJS::SimpleReaderNode::Ptr &node : nodes) { if (variantToStringList(node->property(QStringLiteral("typeNames"))).contains(QString::fromLatin1(typeName))) { const QString fileName = propertyTemplatesPath() + node->property(QStringLiteral("sourceFile")).toString(); QFile file(fileName); @@ -472,10 +505,6 @@ QString PropertyEditorQmlBackend::templateGeneration(const NodeMetaInfo &type, file.close(); const bool section = node->propertyNames().contains("separateSection"); if (section) { - qmlTemplate += "Section {\n"; - qmlTemplate += "anchors.left: parent.left\n"; - qmlTemplate += "anchors.right: parent.right\n"; - qmlTemplate += QString("caption: \"%1\"\n").arg(QString::fromUtf8(properName)); } else if (!sectionStarted) { qmlTemplate += QStringLiteral("Section {\n"); qmlTemplate += QStringLiteral("caption: \"%1\"\n").arg(QString::fromUtf8(type.simplifiedTypeName())); @@ -486,13 +515,12 @@ QString PropertyEditorQmlBackend::templateGeneration(const NodeMetaInfo &type, } qmlTemplate += source.arg(QString::fromUtf8(name)).arg(QString::fromUtf8(properName)); - if (section) - qmlTemplate += "}\n"; emptyTemplate = false; } else { qWarning().nospace() << "template definition source file not found:" << fileName; } } + } } } if (sectionStarted) { @@ -666,3 +694,4 @@ QString PropertyEditorQmlBackend::locateQmlFile(const NodeMetaInfo &info, const } //QmlDesigner + diff --git a/src/plugins/qmldesigner/components/propertyeditor/quick2propertyeditorview.cpp b/src/plugins/qmldesigner/components/propertyeditor/quick2propertyeditorview.cpp index 862d16ba22..e475b982d7 100644 --- a/src/plugins/qmldesigner/components/propertyeditor/quick2propertyeditorview.cpp +++ b/src/plugins/qmldesigner/components/propertyeditor/quick2propertyeditorview.cpp @@ -58,4 +58,31 @@ void Quick2PropertyEditorView::registerQmlTypes() } } +bool Quick2PropertyEditorView::event(QEvent *e) +{ + static std::vector<QKeySequence> overrideSequences = { QKeySequence(Qt::SHIFT + Qt::Key_Up), + QKeySequence(Qt::SHIFT + Qt::Key_Down), + QKeySequence(Qt::CTRL + Qt::Key_Up), + QKeySequence(Qt::CTRL + Qt::Key_Down) + }; + + if (e->type() == QEvent::ShortcutOverride) { + auto keyEvent = static_cast<QKeyEvent *>(e); + + static const Qt::KeyboardModifiers relevantModifiers = Qt::ShiftModifier + | Qt::ControlModifier + | Qt::AltModifier + | Qt::MetaModifier; + + QKeySequence keySqeuence(keyEvent->key() | (keyEvent->modifiers() & relevantModifiers)); + for (const QKeySequence &overrideSequence : overrideSequences) + if (keySqeuence.matches(overrideSequence)) { + keyEvent->accept(); + return true; + } + } + + return QQuickWidget::event(e); +} + } //QmlDesigner diff --git a/src/plugins/qmldesigner/components/propertyeditor/quick2propertyeditorview.h b/src/plugins/qmldesigner/components/propertyeditor/quick2propertyeditorview.h index 7bfc6f1558..c2c0ba9f36 100644 --- a/src/plugins/qmldesigner/components/propertyeditor/quick2propertyeditorview.h +++ b/src/plugins/qmldesigner/components/propertyeditor/quick2propertyeditorview.h @@ -38,6 +38,9 @@ public: explicit Quick2PropertyEditorView(QWidget *parent = nullptr); static void registerQmlTypes(); + +protected: + bool event(QEvent *e) override; }; } //QmlDesigner diff --git a/src/plugins/qmldesigner/components/timelineeditor/timelinemovableabstractitem.h b/src/plugins/qmldesigner/components/timelineeditor/timelinemovableabstractitem.h index 4bc11675c2..0830facfbf 100644 --- a/src/plugins/qmldesigner/components/timelineeditor/timelinemovableabstractitem.h +++ b/src/plugins/qmldesigner/components/timelineeditor/timelinemovableabstractitem.h @@ -75,9 +75,6 @@ protected: void setClampedXPosition(qreal x, qreal min, qreal max); TimelineGraphicsScene *timelineScene() const; - -private: - bool m_multiSelectedMove = false; }; } // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/designercore/instances/nodeinstanceview.cpp b/src/plugins/qmldesigner/designercore/instances/nodeinstanceview.cpp index 62f12d910c..c48bfedce1 100644 --- a/src/plugins/qmldesigner/designercore/instances/nodeinstanceview.cpp +++ b/src/plugins/qmldesigner/designercore/instances/nodeinstanceview.cpp @@ -25,10 +25,6 @@ #include "nodeinstanceview.h" -#include <QUrl> -#include <QMultiHash> -#include <QTimerEvent> - #include <model.h> #include <modelnode.h> #include <metainfo.h> @@ -72,6 +68,12 @@ #include "nodeinstanceserverproxy.h" +#include <utils/algorithm.h> + +#include <QUrl> +#include <QMultiHash> +#include <QTimerEvent> + enum { debug = false }; @@ -1189,7 +1191,7 @@ void NodeInstanceView::pixmapChanged(const PixmapChangedCommand &command) m_nodeInstanceServer->benchmark(Q_FUNC_INFO + QString::number(renderImageChangeSet.count())); if (!renderImageChangeSet.isEmpty()) - emitInstancesRenderImageChanged(renderImageChangeSet.toList().toVector()); + emitInstancesRenderImageChanged(Utils::toList(renderImageChangeSet).toVector()); } QMultiHash<ModelNode, InformationName> NodeInstanceView::informationChanged(const QVector<InformationContainer> &containerVector) diff --git a/src/plugins/qmldesigner/designercore/metainfo/nodemetainfo.cpp b/src/plugins/qmldesigner/designercore/metainfo/nodemetainfo.cpp index 25ff950644..8aacefff55 100644 --- a/src/plugins/qmldesigner/designercore/metainfo/nodemetainfo.cpp +++ b/src/plugins/qmldesigner/designercore/metainfo/nodemetainfo.cpp @@ -336,14 +336,14 @@ private: static inline bool isValueType(const TypeName &type) { static const PropertyTypeList objectValuesList({"QFont", "QPoint", "QPointF", - "QSize", "QSizeF", "QVector3D", "QVector2D"}); + "QSize", "QSizeF", "QVector3D", "QVector2D", "font"}); return objectValuesList.contains(type); } static inline bool isValueType(const QString &type) { static const QStringList objectValuesList({"QFont", "QPoint", "QPointF", - "QSize", "QSizeF", "QVector3D", "QVector2D"}); + "QSize", "QSizeF", "QVector3D", "QVector2D", "font"}); return objectValuesList.contains(type); } diff --git a/src/plugins/qmldesigner/shortcutmanager.cpp b/src/plugins/qmldesigner/shortcutmanager.cpp index 4100d451ee..45e7519474 100644 --- a/src/plugins/qmldesigner/shortcutmanager.cpp +++ b/src/plugins/qmldesigner/shortcutmanager.cpp @@ -178,7 +178,13 @@ void ShortCutManager::registerActions(const Core::Context &qmlDesignerMainContex m_deleteAction.setIcon(QIcon::fromTheme(QLatin1String("edit-cut"), Utils::Icons::EDIT_CLEAR_TOOLBAR.icon())); command = Core::ActionManager::registerAction(&m_deleteAction, QmlDesigner::Constants::C_DELETE, qmlDesignerMainContext); - command->setDefaultKeySequence(QKeySequence::Delete); + if (Utils::HostOsInfo::isMacHost()) + command->setDefaultKeySequence(QKeySequence::Backspace); + else + command->setDefaultKeySequence(QKeySequence::Delete); + + Utils::HostOsInfo::isMacHost() ; + command->setAttribute(Core::Command::CA_Hide); // don't show delete in other modes if (!Utils::HostOsInfo::isMacHost()) editMenu->addAction(command, Core::Constants::G_EDIT_COPYPASTE); diff --git a/src/plugins/qmlprojectmanager/fileformat/filefilteritems.cpp b/src/plugins/qmlprojectmanager/fileformat/filefilteritems.cpp index 9f0a16a921..988c51dbfe 100644 --- a/src/plugins/qmlprojectmanager/fileformat/filefilteritems.cpp +++ b/src/plugins/qmlprojectmanager/fileformat/filefilteritems.cpp @@ -25,6 +25,7 @@ #include "filefilteritems.h" +#include <utils/algorithm.h> #include <utils/filesystemwatcher.h> #include <utils/fileutils.h> #include <utils/qtcassert.h> @@ -160,7 +161,7 @@ void FileFilterBaseItem::setPathsProperty(const QStringList &path) QStringList FileFilterBaseItem::files() const { - return m_files.toList(); + return Utils::toList(m_files); } /** @@ -243,16 +244,16 @@ void FileFilterBaseItem::updateFileListNow() } // update watched directories - const QSet<QString> oldDirs = watchedDirectories().toSet(); + const QSet<QString> oldDirs = Utils::toSet(watchedDirectories()); const QSet<QString> unwatchDirs = oldDirs - dirsToBeWatched; const QSet<QString> watchDirs = dirsToBeWatched - oldDirs; if (!unwatchDirs.isEmpty()) { QTC_ASSERT(m_dirWatcher, return); - m_dirWatcher->removeDirectories(unwatchDirs.toList()); + m_dirWatcher->removeDirectories(Utils::toList(unwatchDirs)); } if (!watchDirs.isEmpty()) - dirWatcher()->addDirectories(watchDirs.toList(), Utils::FileSystemWatcher::WatchAllChanges); + dirWatcher()->addDirectories(Utils::toList(watchDirs), Utils::FileSystemWatcher::WatchAllChanges); } bool FileFilterBaseItem::fileMatches(const QString &fileName) const diff --git a/src/plugins/qmlprojectmanager/qmlproject.cpp b/src/plugins/qmlprojectmanager/qmlproject.cpp index ecfe48378b..114676b315 100644 --- a/src/plugins/qmlprojectmanager/qmlproject.cpp +++ b/src/plugins/qmlprojectmanager/qmlproject.cpp @@ -275,7 +275,7 @@ void QmlProject::refreshFiles(const QSet<QString> &/*added*/, const QSet<QString refresh(Files); if (!removed.isEmpty()) { if (auto modelManager = QmlJS::ModelManagerInterface::instance()) - modelManager->removeFiles(removed.toList()); + modelManager->removeFiles(Utils::toList(removed)); } refreshTargetDirectory(); } diff --git a/src/plugins/qtsupport/qtoutputformatter.cpp b/src/plugins/qtsupport/qtoutputformatter.cpp index 613dddef4c..8fcee4b64d 100644 --- a/src/plugins/qtsupport/qtoutputformatter.cpp +++ b/src/plugins/qtsupport/qtoutputformatter.cpp @@ -242,7 +242,11 @@ void QtOutputFormatter::handleLink(const QString &href) const QRegularExpressionMatch qmlLineMatch = qmlLineLink.match(href); if (qmlLineMatch.hasMatch()) { - const QUrl fileUrl = QUrl(qmlLineMatch.captured(1)); + const char scheme[] = "file://"; + const QString filePath = qmlLineMatch.captured(1); + QUrl fileUrl = QUrl(filePath); + if (!fileUrl.isValid() && filePath.startsWith(scheme)) + fileUrl = QUrl::fromLocalFile(filePath.mid(strlen(scheme))); const int line = qmlLineMatch.captured(2).toInt(); openEditor(getFileToOpen(fileUrl), line); return; @@ -418,15 +422,27 @@ void QtSupportPlugin::testQtOutputFormatter_data() << " Loc: [../TestProject/test.cpp(123)]" << 9 << 37 << "../TestProject/test.cpp(123)" << "../TestProject/test.cpp" << 123 << -1; + + QTest::newRow("Unix relative file link") + << "file://../main.cpp:157" + << 0 << 22 << "file://../main.cpp:157" + << "../main.cpp" << 157 << -1; + if (HostOsInfo::isWindowsHost()) { QTest::newRow("Windows failed QTest link") << "..\\TestProject\\test.cpp(123) : failure location" << 0 << 28 << "..\\TestProject\\test.cpp(123)" << "../TestProject/test.cpp" << 123 << -1; + QTest::newRow("Windows failed QTest link with carriage return") << "..\\TestProject\\test.cpp(123) : failure location\r" << 0 << 28 << "..\\TestProject\\test.cpp(123)" << "../TestProject/test.cpp" << 123 << -1; + + QTest::newRow("Windows relative file link with native separator") + << "file://..\\main.cpp:157" + << 0 << 22 << "file://..\\main.cpp:157" + << "../main.cpp" << 157 << -1; } } diff --git a/src/plugins/qtsupport/qtversionmanager.cpp b/src/plugins/qtsupport/qtversionmanager.cpp index 36e720a8f0..7256d33915 100644 --- a/src/plugins/qtsupport/qtversionmanager.cpp +++ b/src/plugins/qtsupport/qtversionmanager.cpp @@ -422,7 +422,7 @@ static FilePathList gatherQmakePathsFromQtChooser() if (!possibleQMake.isEmpty()) foundQMakes << possibleQMake; } - return foundQMakes.toList(); + return Utils::toList(foundQMakes); } static void findSystemQt() diff --git a/src/plugins/studiowelcome/studiowelcomeplugin.cpp b/src/plugins/studiowelcome/studiowelcomeplugin.cpp index 508ab20b83..57edb46327 100644 --- a/src/plugins/studiowelcome/studiowelcomeplugin.cpp +++ b/src/plugins/studiowelcome/studiowelcomeplugin.cpp @@ -92,6 +92,11 @@ public: ProjectExplorer::ProjectExplorerPlugin::openProjectWelcomePage(projectFile); } + Q_INVOKABLE int get(int) + { + return -1; + } + Q_INVOKABLE void showHelp() { QDesktopServices::openUrl(QUrl("qthelp://org.qt-project.qtcreator/doc/index.html")); diff --git a/src/plugins/texteditor/basefilefind.cpp b/src/plugins/texteditor/basefilefind.cpp index f6c134e02c..b3feef13f0 100644 --- a/src/plugins/texteditor/basefilefind.cpp +++ b/src/plugins/texteditor/basefilefind.cpp @@ -507,7 +507,7 @@ QStringList BaseFileFind::replaceAll(const QString &text, // Query the user for permissions if (!roFiles.isEmpty()) { - ReadOnlyFilesDialog roDialog(roFiles.toList(), ICore::mainWindow()); + ReadOnlyFilesDialog roDialog(Utils::toList(roFiles), ICore::mainWindow()); roDialog.setShowFailWarning(true, tr("Aborting replace.")); if (roDialog.exec() == ReadOnlyFilesDialog::RO_Cancel) return QStringList(); diff --git a/src/plugins/texteditor/codeassist/documentcontentcompletion.cpp b/src/plugins/texteditor/codeassist/documentcontentcompletion.cpp index ee0deab71c..50a04ba88f 100644 --- a/src/plugins/texteditor/codeassist/documentcontentcompletion.cpp +++ b/src/plugins/texteditor/codeassist/documentcontentcompletion.cpp @@ -32,6 +32,7 @@ #include "iassistprocessor.h" #include "../snippets/snippetassistcollector.h" +#include <utils/algorithm.h> #include <utils/runextensions.h> #include <QElapsedTimer> @@ -104,7 +105,7 @@ static void createProposal(QFutureInterface<QStringList> &future, const QString words.insert(word); } - future.reportResult(words.toList()); + future.reportResult(Utils::toList(words)); } IAssistProposal *DocumentContentCompletionProcessor::perform(const AssistInterface *interface) diff --git a/src/plugins/todo/todoitemsprovider.cpp b/src/plugins/todo/todoitemsprovider.cpp index c2f958bb4e..9c8d921567 100644 --- a/src/plugins/todo/todoitemsprovider.cpp +++ b/src/plugins/todo/todoitemsprovider.cpp @@ -123,7 +123,7 @@ void TodoItemsProvider::createScanners() void TodoItemsProvider::setItemsListWithinStartupProject() { QHashIterator<FilePath, QList<TodoItem> > it(m_itemsHash); - const auto filePaths = QSet<FilePath>::fromList(m_startupProject->files(Project::SourceFiles)); + const auto filePaths = Utils::toSet(m_startupProject->files(Project::SourceFiles)); QVariantMap settings = m_startupProject->namedSettings(Constants::SETTINGS_NAME_KEY).toMap(); @@ -159,8 +159,7 @@ void TodoItemsProvider::setItemsListWithinSubproject() }); // files must be both in the current subproject and the startup-project. - const auto fileNames - = QSet<FilePath>::fromList(m_startupProject->files(Project::SourceFiles)); + const auto fileNames = Utils::toSet(m_startupProject->files(Project::SourceFiles)); QHashIterator<FilePath, QList<TodoItem> > it(m_itemsHash); while (it.hasNext()) { it.next(); diff --git a/src/plugins/vcsbase/baseannotationhighlighter.cpp b/src/plugins/vcsbase/baseannotationhighlighter.cpp index 32a0377040..ac23e85394 100644 --- a/src/plugins/vcsbase/baseannotationhighlighter.cpp +++ b/src/plugins/vcsbase/baseannotationhighlighter.cpp @@ -24,9 +24,12 @@ ****************************************************************************/ #include "baseannotationhighlighter.h" + #include <texteditor/fontsettings.h> #include <texteditor/texteditorsettings.h> +#include <utils/algorithm.h> + #include <QDebug> #include <QColor> #include <QTextDocument> @@ -68,7 +71,7 @@ void BaseAnnotationHighlighterPrivate::updateOtherFormats() .toTextCharFormat(TextEditor::C_TEXT) .brushProperty(QTextFormat::BackgroundBrush) .color(); - q->setChangeNumbers(m_changeNumberMap.keys().toSet()); + q->setChangeNumbers(Utils::toSet(m_changeNumberMap.keys())); } BaseAnnotationHighlighter::BaseAnnotationHighlighter(const ChangeNumbers &changeNumbers, diff --git a/src/plugins/vcsbase/vcsbaseeditor.cpp b/src/plugins/vcsbase/vcsbaseeditor.cpp index c6b5ed8fbe..885b0c7cd1 100644 --- a/src/plugins/vcsbase/vcsbaseeditor.cpp +++ b/src/plugins/vcsbase/vcsbaseeditor.cpp @@ -157,7 +157,8 @@ VcsBaseEditor::VcsBaseEditor() void VcsBaseEditor::finalizeInitialization() { - QTC_CHECK(qobject_cast<VcsBaseEditorWidget *>(editorWidget())); + QTC_ASSERT(qobject_cast<VcsBaseEditorWidget *>(editorWidget()), return); + editorWidget()->setReadOnly(true); } // ----------- VcsBaseEditorPrivate diff --git a/src/plugins/vcsbase/vcsbasesubmiteditor.cpp b/src/plugins/vcsbase/vcsbasesubmiteditor.cpp index 3017ae03b9..3d07ced719 100644 --- a/src/plugins/vcsbase/vcsbasesubmiteditor.cpp +++ b/src/plugins/vcsbase/vcsbasesubmiteditor.cpp @@ -37,17 +37,21 @@ #include <aggregation/aggregate.h> #include <cpptools/cppmodelmanager.h> + +#include <coreplugin/find/basetextfind.h> #include <coreplugin/icore.h> #include <coreplugin/editormanager/editormanager.h> + +#include <utils/algorithm.h> #include <utils/checkablemessagebox.h> #include <utils/completingtextedit.h> -#include <utils/synchronousprocess.h> #include <utils/fileutils.h> #include <utils/icon.h> -#include <utils/theme/theme.h> #include <utils/qtcassert.h> +#include <utils/synchronousprocess.h> #include <utils/temporarydirectory.h> -#include <coreplugin/find/basetextfind.h> +#include <utils/theme/theme.h> + #include <texteditor/fontsettings.h> #include <texteditor/texteditorsettings.h> @@ -459,7 +463,7 @@ void VcsBaseSubmitEditor::setFileModel(SubmitFileModel *model) // Populate completer with symbols if (!uniqueSymbols.isEmpty()) { QCompleter *completer = d->m_widget->descriptionEdit()->completer(); - QStringList symbolsList = uniqueSymbols.toList(); + QStringList symbolsList = Utils::toList(uniqueSymbols); symbolsList.sort(); completer->setModel(new QStringListModel(symbolsList, completer)); } diff --git a/src/tools/clangpchmanagerbackend/clangpchmanagerbackendmain.cpp b/src/tools/clangpchmanagerbackend/clangpchmanagerbackendmain.cpp index bcf05e5d04..5a634f8fe1 100644 --- a/src/tools/clangpchmanagerbackend/clangpchmanagerbackendmain.cpp +++ b/src/tools/clangpchmanagerbackend/clangpchmanagerbackendmain.cpp @@ -221,11 +221,13 @@ struct Data // because we have a cycle dependency database}; ClangBackEnd::PchTaskGenerator pchTaskGenerator{buildDependencyProvider, pchTaskMerger, - dependencyCreationProgressCounter}; + dependencyCreationProgressCounter, + pchTaskQueue}; PchManagerServer clangPchManagerServer{includeWatcher, pchTaskGenerator, projectParts, - generatedFiles}; + generatedFiles, + buildDependencyStorage}; TaskScheduler systemTaskScheduler{pchCreatorManager, pchTaskQueue, pchCreationProgressCounter, diff --git a/src/tools/clangpchmanagerbackend/source/builddependenciesstorage.h b/src/tools/clangpchmanagerbackend/source/builddependenciesstorage.h index 187a27cf89..00bb429dba 100644 --- a/src/tools/clangpchmanagerbackend/source/builddependenciesstorage.h +++ b/src/tools/clangpchmanagerbackend/source/builddependenciesstorage.h @@ -71,6 +71,11 @@ public: return fetchPchSourcesStatement.template values<FilePathId>(1024, projectPartId.projectPathId); } + FilePathIds fetchSources(ProjectPartId projectPartId) const override + { + return fetchSourcesStatement.template values<FilePathId>(1024, projectPartId.projectPathId); + } + void insertOrUpdateFileStatuses(const FileStatuses &fileStatuses) override { WriteStatement &statement = insertOrUpdateFileStatusesStatement; @@ -144,6 +149,94 @@ public: transaction.commit(); } + void insertOrUpdateIndexingTimeStamps(const FilePathIds &filePathIds, + TimeStamp indexingTimeStamp) override + { + try { + Sqlite::ImmediateTransaction transaction{database}; + + for (FilePathId filePathId : filePathIds) { + inserOrUpdateIndexingTimesStampStatement.write(filePathId.filePathId, + indexingTimeStamp.value); + } + + transaction.commit(); + } catch (const Sqlite::StatementIsBusy &) { + insertOrUpdateIndexingTimeStamps(filePathIds, indexingTimeStamp); + } + } + + void insertOrUpdateIndexingTimeStamps(const FileStatuses &fileStatuses) override + { + for (FileStatus fileStatus : fileStatuses) { + inserOrUpdateIndexingTimesStampStatement.write(fileStatus.filePathId.filePathId, + fileStatus.lastModified); + } + } + + SourceTimeStamps fetchIndexingTimeStamps() const override + { + try { + Sqlite::DeferredTransaction transaction{database}; + + auto timeStamps = fetchIndexingTimeStampsStatement.template values<SourceTimeStamp, 2>( + 1024); + + transaction.commit(); + + return timeStamps; + } catch (const Sqlite::StatementIsBusy &) { + return fetchIndexingTimeStamps(); + } + } + + SourceTimeStamps fetchIncludedIndexingTimeStamps(FilePathId sourcePathId) const override + { + try { + Sqlite::DeferredTransaction transaction{database}; + + auto timeStamps = fetchIncludedIndexingTimeStampsStatement + .template values<SourceTimeStamp, 2>(1024, sourcePathId.filePathId); + + transaction.commit(); + + return timeStamps; + } catch (const Sqlite::StatementIsBusy &) { + return fetchIncludedIndexingTimeStamps(sourcePathId); + } + } + + FilePathIds fetchDependentSourceIds(const FilePathIds &sourcePathIds) const override + { + try { + FilePathIds dependentSourceIds; + + Sqlite::DeferredTransaction transaction{database}; + + for (FilePathId sourcePathId : sourcePathIds) { + FilePathIds newDependentSourceIds; + newDependentSourceIds.reserve(dependentSourceIds.size() + 1024); + + auto newIds = fetchDependentSourceIdsStatement + .template values<FilePathId>(1024, sourcePathId.filePathId); + + std::set_union(dependentSourceIds.begin(), + dependentSourceIds.end(), + newIds.begin(), + newIds.end(), + std::back_inserter(newDependentSourceIds)); + + dependentSourceIds = std::move(newDependentSourceIds); + } + + transaction.commit(); + + return dependentSourceIds; + } catch (const Sqlite::StatementIsBusy &) { + return fetchDependentSourceIds(sourcePathIds); + } + } + static Utils::SmallString toJson(const Utils::SmallStringVector &strings) { QJsonDocument document; @@ -255,6 +348,8 @@ public: "SELECT sourceId FROM projectPartsFiles WHERE projectPartId = ? AND sourceType IN (0, 1, " "3, 4) ORDER BY sourceId", database}; + mutable ReadStatement fetchSourcesStatement{ + "SELECT sourceId FROM projectPartsFiles WHERE projectPartId = ? ORDER BY sourceId", database}; mutable ReadStatement fetchSourceDependenciesStatement{ "WITH RECURSIVE collectedDependencies(sourceId) AS (VALUES(?) UNION " "SELECT dependencySourceId FROM sourceDependencies, " @@ -279,5 +374,24 @@ public: database}; WriteStatement deleteAllProjectPartsFilesWithProjectPartNameStatement{ "DELETE FROM projectPartsFiles WHERE projectPartId = ?", database}; + WriteStatement inserOrUpdateIndexingTimesStampStatement{ + "INSERT INTO fileStatuses(sourceId, indexingTimeStamp) VALUES (?001, ?002) ON " + "CONFLICT(sourceId) DO UPDATE SET indexingTimeStamp = ?002", + database}; + mutable ReadStatement fetchIncludedIndexingTimeStampsStatement{ + "WITH RECURSIVE collectedDependencies(sourceId) AS (VALUES(?) UNION SELECT " + "dependencySourceId FROM sourceDependencies, collectedDependencies WHERE " + "sourceDependencies.sourceId == collectedDependencies.sourceId) SELECT DISTINCT sourceId, " + "indexingTimeStamp FROM collectedDependencies NATURAL JOIN fileStatuses ORDER BY sourceId", + database}; + mutable ReadStatement fetchIndexingTimeStampsStatement{ + "SELECT sourceId, indexingTimeStamp FROM fileStatuses", database}; + mutable ReadStatement fetchDependentSourceIdsStatement{ + "WITH RECURSIVE collectedDependencies(sourceId) AS (VALUES(?) UNION SELECT " + "sourceDependencies.sourceId FROM sourceDependencies, collectedDependencies WHERE " + "sourceDependencies.dependencySourceId == collectedDependencies.sourceId) SELECT sourceId " + "FROM collectedDependencies WHERE sourceId NOT IN (SELECT dependencySourceId FROM " + "sourceDependencies) ORDER BY sourceId", + database}; }; } diff --git a/src/tools/clangpchmanagerbackend/source/builddependenciesstorageinterface.h b/src/tools/clangpchmanagerbackend/source/builddependenciesstorageinterface.h index a1c20811aa..953f2cca42 100644 --- a/src/tools/clangpchmanagerbackend/source/builddependenciesstorageinterface.h +++ b/src/tools/clangpchmanagerbackend/source/builddependenciesstorageinterface.h @@ -57,6 +57,12 @@ public: virtual ProjectPartId fetchProjectPartId(Utils::SmallStringView projectPartName) = 0; virtual void updatePchCreationTimeStamp(long long pchCreationTimeStamp, ProjectPartId projectPartId) = 0; virtual FilePathIds fetchPchSources(ProjectPartId projectPartId) const = 0; + virtual FilePathIds fetchSources(ProjectPartId projectPartId) const = 0; + virtual void insertOrUpdateIndexingTimeStamps(const FilePathIds &filePathIds, TimeStamp indexingTimeStamp) = 0; + virtual void insertOrUpdateIndexingTimeStamps(const FileStatuses &fileStatuses) = 0; + virtual SourceTimeStamps fetchIndexingTimeStamps() const = 0; + virtual SourceTimeStamps fetchIncludedIndexingTimeStamps(FilePathId sourcePathId) const = 0; + virtual FilePathIds fetchDependentSourceIds(const FilePathIds &sourcePathIds) const = 0; protected: ~BuildDependenciesStorageInterface() = default; diff --git a/src/tools/clangpchmanagerbackend/source/pchcreator.cpp b/src/tools/clangpchmanagerbackend/source/pchcreator.cpp index 15c9a19547..46562c39a9 100644 --- a/src/tools/clangpchmanagerbackend/source/pchcreator.cpp +++ b/src/tools/clangpchmanagerbackend/source/pchcreator.cpp @@ -45,6 +45,8 @@ #include <QProcess> #include <QTemporaryFile> +#include <iostream> + namespace ClangBackEnd { namespace { @@ -110,11 +112,28 @@ Utils::SmallStringVector PchCreator::generateClangCompilerArguments(const PchTas return builder.commandLine; } +FilePathIds PchCreator::existingSources(FilePathIds sources) const +{ + FilePathIds existingSources; + existingSources.reserve(sources.size()); + std::set_difference(sources.begin(), + sources.end(), + m_generatedFilePathIds.begin(), + m_generatedFilePathIds.end(), + std::back_inserter(existingSources)); + + return existingSources; +} + void PchCreator::generatePch(PchTask &&pchTask) { m_projectPartPch.projectPartId = pchTask.projectPartId(); m_projectPartPch.lastModified = QDateTime::currentSecsSinceEpoch(); - m_sources = std::move(pchTask.sources); + m_watchedSystemIncludes = std::move(pchTask.watchedSystemIncludes); + m_watchedProjectIncludes = std::move(pchTask.watchedProjectIncludes); + m_watchedUserIncludes = std::move(pchTask.watchedUserIncludes); + m_watchedSources = std::move(pchTask.watchedUserSources); + if (pchTask.includes.empty()) return; @@ -166,23 +185,26 @@ void PchCreator::clear() { m_clangTool = ClangTool{}; m_projectPartPch = {}; - m_sources.clear(); + m_watchedSystemIncludes.clear(); + m_watchedProjectIncludes.clear(); + m_watchedUserIncludes.clear(); + m_watchedSources.clear(); } void PchCreator::doInMainThreadAfterFinished() { if (m_projectPartPch.projectPartId.isValid()) { - FilePathIds existingSources; - existingSources.reserve(m_sources.size()); - std::set_difference(m_sources.begin(), - m_sources.end(), - m_generatedFilePathIds.begin(), - m_generatedFilePathIds.end(), - std::back_inserter(existingSources)); m_buildDependenciesStorage.updatePchCreationTimeStamp(m_projectPartPch.lastModified, m_projectPartPch.projectPartId); - m_clangPathwatcher.updateIdPaths({{m_projectPartPch.projectPartId, existingSources}}); - m_pchManagerClient.precompiledHeadersUpdated({m_projectPartPch.projectPartId}); + m_clangPathwatcher.updateIdPaths({{{m_projectPartPch.projectPartId, SourceType::Source}, + existingSources(m_watchedSources)}}); + m_clangPathwatcher.updateIdPaths({{{m_projectPartPch.projectPartId, SourceType::UserInclude}, + existingSources(m_watchedUserIncludes)}}); + m_clangPathwatcher.updateIdPaths({{{m_projectPartPch.projectPartId, SourceType::ProjectInclude}, + existingSources(m_watchedProjectIncludes)}}); + m_clangPathwatcher.updateIdPaths({{{m_projectPartPch.projectPartId, SourceType::SystemInclude}, + existingSources(m_watchedSystemIncludes)}}); + m_pchManagerClient.precompiledHeadersUpdated(m_projectPartPch.projectPartId); } } diff --git a/src/tools/clangpchmanagerbackend/source/pchcreator.h b/src/tools/clangpchmanagerbackend/source/pchcreator.h index f1fadcd33a..c30e011011 100644 --- a/src/tools/clangpchmanagerbackend/source/pchcreator.h +++ b/src/tools/clangpchmanagerbackend/source/pchcreator.h @@ -80,19 +80,24 @@ public: static Utils::SmallStringVector generateClangCompilerArguments(const PchTask &pchTask, FilePathView pchPath); - const ClangTool &clangTool() const - { - return m_clangTool; - } + const ClangTool &clangTool() const { return m_clangTool; } - const FilePathIds &sources() const { return m_sources; } + FilePathIds existingSources(FilePathIds sources) const; + + const FilePathIds &watchedSystemIncludes() const { return m_watchedSystemIncludes; } + const FilePathIds &watchedProjectIncludes() const { return m_watchedProjectIncludes; } + const FilePathIds &watchedUserIncludes() const { return m_watchedUserIncludes; } + const FilePathIds &watchedSources() const { return m_watchedSources; } private: mutable std::mt19937_64 randomNumberGenator{std::random_device{}()}; ClangTool m_clangTool; ProjectPartPch m_projectPartPch; FilePathCaching m_filePathCache; - FilePathIds m_sources; + FilePathIds m_watchedSystemIncludes; + FilePathIds m_watchedProjectIncludes; + FilePathIds m_watchedUserIncludes; + FilePathIds m_watchedSources; FilePathIds m_generatedFilePathIds; Environment &m_environment; PchManagerClientInterface &m_pchManagerClient; diff --git a/src/tools/clangpchmanagerbackend/source/pchmanagerserver.cpp b/src/tools/clangpchmanagerbackend/source/pchmanagerserver.cpp index 9cce6ef469..ec0d89d2c6 100644 --- a/src/tools/clangpchmanagerbackend/source/pchmanagerserver.cpp +++ b/src/tools/clangpchmanagerbackend/source/pchmanagerserver.cpp @@ -25,10 +25,11 @@ #include "pchmanagerserver.h" +#include <builddependenciesstorage.h> #include <pchmanagerclientinterface.h> +#include <pchtaskgeneratorinterface.h> #include <precompiledheadersupdatedmessage.h> #include <progressmessage.h> -#include <pchtaskgeneratorinterface.h> #include <removegeneratedfilesmessage.h> #include <removeprojectpartsmessage.h> #include <updategeneratedfilesmessage.h> @@ -39,16 +40,20 @@ #include <QApplication> +#include <algorithm> + namespace ClangBackEnd { PchManagerServer::PchManagerServer(ClangPathWatcherInterface &fileSystemWatcher, PchTaskGeneratorInterface &pchTaskGenerator, ProjectPartsManagerInterface &projectParts, - GeneratedFilesInterface &generatedFiles) + GeneratedFilesInterface &generatedFiles, + BuildDependenciesStorageInterface &buildDependenciesStorage) : m_fileSystemWatcher(fileSystemWatcher) , m_pchTaskGenerator(pchTaskGenerator) , m_projectPartsManager(projectParts) , m_generatedFiles(generatedFiles) + , m_buildDependenciesStorage(buildDependenciesStorage) { m_fileSystemWatcher.setNotifier(this); } @@ -130,18 +135,92 @@ void PchManagerServer::removeGeneratedFiles(RemoveGeneratedFilesMessage &&messag m_generatedFiles.remove(message.takeGeneratedFiles()); } -void PchManagerServer::pathsWithIdsChanged(const ProjectPartIds &ids) +namespace { +struct FilterResults { - ArgumentsEntries entries = m_toolChainsArgumentsCache.arguments(ids); + ProjectPartIds systemIds; + ProjectPartIds projectIds; + ProjectPartIds userIds; +}; - for (ArgumentsEntry &entry : entries) { - m_pchTaskGenerator.addProjectParts(m_projectPartsManager.projects(entry.ids), - std::move(entry.arguments)); +ProjectPartIds removeIds(const ProjectPartIds &subtrahend, const ProjectPartIds &minuend) +{ + ProjectPartIds difference; + difference.reserve(subtrahend.size()); + + std::set_difference(subtrahend.begin(), + subtrahend.end(), + minuend.begin(), + minuend.end(), + std::back_inserter(difference)); + + return difference; +} + +FilterResults pchProjectPartIds(const std::vector<IdPaths> &idPaths) +{ + ProjectPartIds changedUserProjectPartIds; + changedUserProjectPartIds.reserve(idPaths.size()); + + ProjectPartIds changedSystemPchProjectPartIds; + changedSystemPchProjectPartIds.reserve(idPaths.size()); + + ProjectPartIds changedProjectPchProjectPartIds; + changedProjectPchProjectPartIds.reserve(idPaths.size()); + + for (const IdPaths &idPath : idPaths) { + switch (idPath.id.sourceType) { + case SourceType::TopSystemInclude: + case SourceType::SystemInclude: + changedSystemPchProjectPartIds.push_back(idPath.id.id); + break; + case SourceType::TopProjectInclude: + case SourceType::ProjectInclude: + changedProjectPchProjectPartIds.push_back(idPath.id.id); + break; + case SourceType::UserInclude: + case SourceType::Source: + changedUserProjectPartIds.push_back(idPath.id.id); + break; + } } + + changedSystemPchProjectPartIds.erase(std::unique(changedSystemPchProjectPartIds.begin(), + changedSystemPchProjectPartIds.end()), + changedSystemPchProjectPartIds.end()); + changedProjectPchProjectPartIds.erase(std::unique(changedProjectPchProjectPartIds.begin(), + changedProjectPchProjectPartIds.end()), + changedProjectPchProjectPartIds.end()); + changedUserProjectPartIds.erase(std::unique(changedUserProjectPartIds.begin(), + changedUserProjectPartIds.end()), + changedUserProjectPartIds.end()); + + changedProjectPchProjectPartIds = removeIds(changedProjectPchProjectPartIds, + changedSystemPchProjectPartIds); + + changedUserProjectPartIds = removeIds(changedUserProjectPartIds, changedSystemPchProjectPartIds); + changedUserProjectPartIds = removeIds(changedUserProjectPartIds, changedProjectPchProjectPartIds); + + return {std::move(changedSystemPchProjectPartIds), + std::move(changedProjectPchProjectPartIds), + std::move(changedUserProjectPartIds)}; } +} // namespace -void PchManagerServer::pathsChanged(const FilePathIds &/*filePathIds*/) +void PchManagerServer::pathsWithIdsChanged(const std::vector<IdPaths> &idPaths) { + auto changedProjectPartIds = pchProjectPartIds(idPaths); + + addCompleteProjectParts(changedProjectPartIds.systemIds); + + addNonSystemProjectParts(changedProjectPartIds.projectIds); + + client()->precompiledHeadersUpdated(std::move(changedProjectPartIds.userIds)); +} + +void PchManagerServer::pathsChanged(const FilePathIds &filePathIds) +{ + m_buildDependenciesStorage.insertOrUpdateIndexingTimeStamps(filePathIds, 0); } void PchManagerServer::setPchCreationProgress(int progress, int total) @@ -154,4 +233,24 @@ void PchManagerServer::setDependencyCreationProgress(int progress, int total) client()->progress({ProgressType::DependencyCreation, progress, total}); } +void PchManagerServer::addCompleteProjectParts(const ProjectPartIds &projectPartIds) +{ + ArgumentsEntries entries = m_toolChainsArgumentsCache.arguments(projectPartIds); + + for (ArgumentsEntry &entry : entries) { + m_pchTaskGenerator.addProjectParts(m_projectPartsManager.projects(entry.ids), + std::move(entry.arguments)); + } +} + +void PchManagerServer::addNonSystemProjectParts(const ProjectPartIds &projectPartIds) +{ + ArgumentsEntries entries = m_toolChainsArgumentsCache.arguments(projectPartIds); + + for (ArgumentsEntry &entry : entries) { + m_pchTaskGenerator.addNonSystemProjectParts(m_projectPartsManager.projects(entry.ids), + std::move(entry.arguments)); + } +} + } // namespace ClangBackEnd diff --git a/src/tools/clangpchmanagerbackend/source/pchmanagerserver.h b/src/tools/clangpchmanagerbackend/source/pchmanagerserver.h index cc9daa7aa4..c8e5be4de5 100644 --- a/src/tools/clangpchmanagerbackend/source/pchmanagerserver.h +++ b/src/tools/clangpchmanagerbackend/source/pchmanagerserver.h @@ -39,6 +39,7 @@ namespace ClangBackEnd { class SourceRangesAndDiagnosticsForQueryMessage; class PchTaskGeneratorInterface; +class BuildDependenciesStorageInterface; class PchManagerServer : public PchManagerServerInterface, public ClangPathWatcherNotifier, @@ -49,7 +50,8 @@ public: PchManagerServer(ClangPathWatcherInterface &fileSystemWatcher, PchTaskGeneratorInterface &pchTaskGenerator, ProjectPartsManagerInterface &projectParts, - GeneratedFilesInterface &generatedFiles); + GeneratedFilesInterface &generatedFiles, + BuildDependenciesStorageInterface &buildDependenciesStorage); void end() override; void updateProjectParts(UpdateProjectPartsMessage &&message) override; @@ -57,17 +59,22 @@ public: void updateGeneratedFiles(UpdateGeneratedFilesMessage &&message) override; void removeGeneratedFiles(RemoveGeneratedFilesMessage &&message) override; - void pathsWithIdsChanged(const ProjectPartIds &ids) override; + void pathsWithIdsChanged(const std::vector<IdPaths> &idPaths) override; void pathsChanged(const FilePathIds &filePathIds) override; void setPchCreationProgress(int progress, int total); void setDependencyCreationProgress(int progress, int total); private: + void addCompleteProjectParts(const ProjectPartIds &projectPartIds); + void addNonSystemProjectParts(const ProjectPartIds &projectPartIds); + +private: ClangPathWatcherInterface &m_fileSystemWatcher; PchTaskGeneratorInterface &m_pchTaskGenerator; ProjectPartsManagerInterface &m_projectPartsManager; GeneratedFilesInterface &m_generatedFiles; + BuildDependenciesStorageInterface &m_buildDependenciesStorage; ToolChainsArgumentsCache m_toolChainsArgumentsCache; }; diff --git a/src/tools/clangpchmanagerbackend/source/pchtask.h b/src/tools/clangpchmanagerbackend/source/pchtask.h index 74b410831e..f71a2745ad 100644 --- a/src/tools/clangpchmanagerbackend/source/pchtask.h +++ b/src/tools/clangpchmanagerbackend/source/pchtask.h @@ -42,7 +42,10 @@ class PchTask public: PchTask(ProjectPartId projectPartId, FilePathIds &&includes, - FilePathIds &&sources, + FilePathIds &&watchedSystemIncludes, + FilePathIds &&watchedProjectIncludes, + FilePathIds &&watchedUserIncludes, + FilePathIds &&watchedUserSources, CompilerMacros &&compilerMacros, Utils::SmallStringVector &&usedMacros, // TODO remove Utils::SmallStringVector toolChainArguments, @@ -53,7 +56,10 @@ public: Utils::LanguageExtension languageExtension = Utils::LanguageExtension::None) : projectPartIds({projectPartId}) , includes(includes) - , sources(sources) + , watchedSystemIncludes(watchedSystemIncludes) + , watchedProjectIncludes(watchedProjectIncludes) + , watchedUserIncludes(watchedUserIncludes) + , watchedUserSources(watchedUserSources) , compilerMacros(compilerMacros) , systemIncludeSearchPaths(std::move(systemIncludeSearchPaths)) , projectIncludeSearchPaths(std::move(projectIncludeSearchPaths)) @@ -65,7 +71,10 @@ public: PchTask(ProjectPartIds &&projectPartIds, FilePathIds &&includes, - FilePathIds &&sources, + FilePathIds &&watchedSystemIncludes, + FilePathIds &&watchedProjectIncludes, + FilePathIds &&watchedUserIncludes, + FilePathIds &&watchedUserSources, CompilerMacros &&compilerMacros, Utils::SmallStringVector &&usedMacros, // TODO remove Utils::SmallStringVector toolChainArguments, @@ -76,7 +85,10 @@ public: Utils::LanguageExtension languageExtension = Utils::LanguageExtension::None) : projectPartIds(std::move(projectPartIds)) , includes(includes) - , sources(sources) + , watchedSystemIncludes(watchedSystemIncludes) + , watchedProjectIncludes(watchedProjectIncludes) + , watchedUserIncludes(watchedUserIncludes) + , watchedUserSources(watchedUserSources) , compilerMacros(compilerMacros) , systemIncludeSearchPaths(std::move(systemIncludeSearchPaths)) , projectIncludeSearchPaths(std::move(projectIncludeSearchPaths)) @@ -90,6 +102,10 @@ public: { return first.systemPchPath == second.systemPchPath && first.projectPartIds == second.projectPartIds && first.includes == second.includes + && first.watchedSystemIncludes == second.watchedSystemIncludes + && first.watchedProjectIncludes == second.watchedProjectIncludes + && first.watchedUserIncludes == second.watchedUserIncludes + && first.watchedUserSources == second.watchedUserSources && first.compilerMacros == second.compilerMacros && first.systemIncludeSearchPaths == second.systemIncludeSearchPaths && first.projectIncludeSearchPaths == second.projectIncludeSearchPaths @@ -105,7 +121,10 @@ public: FilePath systemPchPath; ProjectPartIds projectPartIds; FilePathIds includes; - FilePathIds sources; + FilePathIds watchedSystemIncludes; + FilePathIds watchedProjectIncludes; + FilePathIds watchedUserIncludes; + FilePathIds watchedUserSources; CompilerMacros compilerMacros; IncludeSearchPaths systemIncludeSearchPaths; IncludeSearchPaths projectIncludeSearchPaths; diff --git a/src/tools/clangpchmanagerbackend/source/pchtaskgenerator.cpp b/src/tools/clangpchmanagerbackend/source/pchtaskgenerator.cpp index c0a42eae39..7fe75d4779 100644 --- a/src/tools/clangpchmanagerbackend/source/pchtaskgenerator.cpp +++ b/src/tools/clangpchmanagerbackend/source/pchtaskgenerator.cpp @@ -26,6 +26,7 @@ #include "pchtaskgenerator.h" #include "builddependenciesproviderinterface.h" +#include "pchtaskqueueinterface.h" #include "pchtasksmergerinterface.h" #include "usedmacrofilter.h" @@ -52,6 +53,9 @@ void PchTaskGenerator::addProjectParts(ProjectPartContainers &&projectParts, pchTaskSets.emplace_back(PchTask{projectPart.projectPartId, std::move(filter.topSystemIncludes), {}, + {}, + {}, + {}, std::move(filter.systemCompilerMacros), std::move(filter.systemUsedMacros), projectPart.toolChainArguments, @@ -62,6 +66,9 @@ void PchTaskGenerator::addProjectParts(ProjectPartContainers &&projectParts, projectPart.languageExtension}, PchTask{projectPart.projectPartId, std::move(filter.topProjectIncludes), + std::move(filter.systemIncludes), + std::move(filter.projectIncludes), + std::move(filter.userIncludes), std::move(filter.sources), std::move(filter.projectCompilerMacros), std::move(filter.projectUsedMacros), @@ -82,4 +89,38 @@ void PchTaskGenerator::removeProjectParts(const ProjectPartIds &projectsPartIds) m_pchTasksMergerInterface.removePchTasks(projectsPartIds); } +void PchTaskGenerator::addNonSystemProjectParts(ProjectPartContainers &&projectParts, + Utils::SmallStringVector &&) +{ + PchTasks pchTasks; + pchTasks.reserve(projectParts.size()); + + m_progressCounter.addTotal(static_cast<int>(projectParts.size())); + + for (auto &projectPart : projectParts) { + BuildDependency buildDependency = m_buildDependenciesProvider.create(projectPart); + UsedMacroFilter filter{buildDependency.sources, + buildDependency.usedMacros, + projectPart.compilerMacros}; + + pchTasks.emplace_back(projectPart.projectPartId, + std::move(filter.topProjectIncludes), + std::move(filter.systemIncludes), + std::move(filter.projectIncludes), + std::move(filter.userIncludes), + std::move(filter.sources), + std::move(filter.projectCompilerMacros), + std::move(filter.projectUsedMacros), + projectPart.toolChainArguments, + projectPart.systemIncludeSearchPaths, + projectPart.projectIncludeSearchPaths, + projectPart.language, + projectPart.languageVersion, + projectPart.languageExtension); + m_progressCounter.addProgress(1); + } + + m_pchTaskQueue.addProjectPchTasks(std::move(pchTasks)); +} + } // namespace ClangBackEnd diff --git a/src/tools/clangpchmanagerbackend/source/pchtaskgenerator.h b/src/tools/clangpchmanagerbackend/source/pchtaskgenerator.h index dc7d201cde..be3d91c892 100644 --- a/src/tools/clangpchmanagerbackend/source/pchtaskgenerator.h +++ b/src/tools/clangpchmanagerbackend/source/pchtaskgenerator.h @@ -35,6 +35,7 @@ namespace ClangBackEnd { class PchTasksMergerInterface; class BuildDependenciesProviderInterface; +class PchTaskQueueInterface; class ProgressCounter; class PchTaskGenerator : public PchTaskGeneratorInterface @@ -42,21 +43,26 @@ class PchTaskGenerator : public PchTaskGeneratorInterface public: PchTaskGenerator(BuildDependenciesProviderInterface &buildDependenciesProvider, PchTasksMergerInterface &pchTasksMergerInterface, - ProgressCounter &progressCounter) + ProgressCounter &progressCounter, + PchTaskQueueInterface &pchTaskQueue) : m_buildDependenciesProvider(buildDependenciesProvider) , m_pchTasksMergerInterface(pchTasksMergerInterface) , m_progressCounter(progressCounter) + , m_pchTaskQueue(pchTaskQueue) {} void addProjectParts(ProjectPartContainers &&projectParts, Utils::SmallStringVector &&toolChainArguments) override; void removeProjectParts(const ProjectPartIds &projectsPartIds) override; + void addNonSystemProjectParts(ProjectPartContainers &&projectParts, + Utils::SmallStringVector &&toolChainArguments) override; private: BuildDependenciesProviderInterface &m_buildDependenciesProvider; PchTasksMergerInterface &m_pchTasksMergerInterface; ProgressCounter &m_progressCounter; + PchTaskQueueInterface &m_pchTaskQueue; }; } // namespace ClangBackEnd diff --git a/src/tools/clangpchmanagerbackend/source/pchtaskgeneratorinterface.h b/src/tools/clangpchmanagerbackend/source/pchtaskgeneratorinterface.h index abb25d2ef1..302789ae9a 100644 --- a/src/tools/clangpchmanagerbackend/source/pchtaskgeneratorinterface.h +++ b/src/tools/clangpchmanagerbackend/source/pchtaskgeneratorinterface.h @@ -35,6 +35,9 @@ public: virtual void addProjectParts(ProjectPartContainers &&projectParts, Utils::SmallStringVector &&toolChainArguments) = 0; + virtual void addNonSystemProjectParts(ProjectPartContainers &&projectParts, + Utils::SmallStringVector &&toolChainArguments) + = 0; virtual void removeProjectParts(const ProjectPartIds &projectsPartIds) = 0; protected: diff --git a/src/tools/clangpchmanagerbackend/source/pchtasksmerger.cpp b/src/tools/clangpchmanagerbackend/source/pchtasksmerger.cpp index 68a8e4a642..6436c0a0b4 100644 --- a/src/tools/clangpchmanagerbackend/source/pchtasksmerger.cpp +++ b/src/tools/clangpchmanagerbackend/source/pchtasksmerger.cpp @@ -98,8 +98,8 @@ bool PchTasksMerger::mergePchTasks(PchTask &firstTask, PchTask &secondTask) firstTask.projectPartIds = merge(std::move(firstTask.projectPartIds), std::move(secondTask.projectPartIds)); firstTask.includes = merge(std::move(firstTask.includes), std::move(secondTask.includes)); - firstTask.sources = merge(std::move(firstTask.sources), - std::move(secondTask.sources)); + firstTask.watchedSystemIncludes = merge(std::move(firstTask.watchedSystemIncludes), + std::move(secondTask.watchedSystemIncludes)); firstTask.compilerMacros = std::move(macros); firstTask.systemIncludeSearchPaths = mergeIncludeSearchPaths( std::move(firstTask.systemIncludeSearchPaths), diff --git a/src/tools/clangpchmanagerbackend/source/usedmacrofilter.h b/src/tools/clangpchmanagerbackend/source/usedmacrofilter.h index 2d16b484a1..63bb503e75 100644 --- a/src/tools/clangpchmanagerbackend/source/usedmacrofilter.h +++ b/src/tools/clangpchmanagerbackend/source/usedmacrofilter.h @@ -99,6 +99,7 @@ public: projectIncludes.reserve(sources.size()); topSystemIncludes.reserve(sources.size() / 10); topProjectIncludes.reserve(sources.size() / 10); + userIncludes.reserve(sources.size()); this->sources.reserve(sources.size()); for (SourceEntry source : sources) @@ -128,23 +129,22 @@ private: case SourceType::TopSystemInclude: topSystemIncludes.emplace_back(source.sourceId); systemIncludes.emplace_back(source.sourceId); - sources.emplace_back(source.sourceId); break; case SourceType::SystemInclude: systemIncludes.emplace_back(source.sourceId); - sources.emplace_back(source.sourceId); break; case SourceType::TopProjectInclude: topProjectIncludes.emplace_back(source.sourceId); projectIncludes.emplace_back(source.sourceId); - sources.emplace_back(source.sourceId); break; case SourceType::ProjectInclude: projectIncludes.emplace_back(source.sourceId); - sources.emplace_back(source.sourceId); break; case SourceType::UserInclude: + userIncludes.emplace_back(source.sourceId); + break; case SourceType::Source: + sources.emplace_back(source.sourceId); break; } @@ -215,6 +215,7 @@ private: public: FilePathIds sources; + FilePathIds userIncludes; FilePathIds projectIncludes; FilePathIds systemIncludes; FilePathIds topProjectIncludes; diff --git a/src/tools/clangrefactoringbackend/source/CMakeLists.txt b/src/tools/clangrefactoringbackend/source/CMakeLists.txt index d43472fd60..6c149bf9cd 100644 --- a/src/tools/clangrefactoringbackend/source/CMakeLists.txt +++ b/src/tools/clangrefactoringbackend/source/CMakeLists.txt @@ -18,8 +18,6 @@ add_qtc_library(clangrefactoringbackend_lib STATIC collectmacrospreprocessorcallbacks.h collectmacrossourcefilecallbacks.cpp collectmacrossourcefilecallbacks.h collectsymbolsaction.cpp collectsymbolsaction.h - filestatus.h - filestatuscache.cpp filestatuscache.h filestatuspreprocessorcallbacks.cpp filestatuspreprocessorcallbacks.h findcursorusr.h findlocationsofusrs.h diff --git a/src/tools/clangrefactoringbackend/source/clangrefactoringbackend-source.pri b/src/tools/clangrefactoringbackend/source/clangrefactoringbackend-source.pri index a3da84d83b..9c51093632 100644 --- a/src/tools/clangrefactoringbackend/source/clangrefactoringbackend-source.pri +++ b/src/tools/clangrefactoringbackend/source/clangrefactoringbackend-source.pri @@ -26,11 +26,8 @@ HEADERS += \ !isEmpty(LIBTOOLING_LIBS) { SOURCES += \ $$PWD/refactoringcompilationdatabase.cpp \ - $$PWD/symbolfinder.cpp \ - $$PWD/symbollocationfinderaction.cpp \ $$PWD/refactoringserver.cpp \ $$PWD/macropreprocessorcallbacks.cpp \ - $$PWD/findusrforcursoraction.cpp \ $$PWD/clangquery.cpp \ $$PWD/clangtool.cpp \ $$PWD/sourcerangeextractor.cpp \ @@ -44,14 +41,10 @@ SOURCES += \ HEADERS += \ $$PWD/refactoringcompilationdatabase.h \ - $$PWD/symbolfinder.h \ - $$PWD/symbollocationfinderaction.h \ $$PWD/refactoringserver.h \ $$PWD/macropreprocessorcallbacks.h \ $$PWD/sourcelocationsutils.h \ $$PWD/findcursorusr.h \ - $$PWD/findusrforcursoraction.h \ - $$PWD/findlocationsofusrs.h \ $$PWD/clangquery.h \ $$PWD/clangtool.h \ $$PWD/sourcerangeextractor.h \ diff --git a/src/tools/clangrefactoringbackend/source/findcursorusr.h b/src/tools/clangrefactoringbackend/source/findcursorusr.h deleted file mode 100644 index 06777d8611..0000000000 --- a/src/tools/clangrefactoringbackend/source/findcursorusr.h +++ /dev/null @@ -1,191 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt Creator. -** -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -****************************************************************************/ - -#pragma once - -#include "clangrefactoringbackend_global.h" - -#include <clang/AST/AST.h> -#include <clang/AST/ASTContext.h> -#include <clang/AST/RecursiveASTVisitor.h> -#include <clang/Index/USRGeneration.h> -#include <llvm/ADT/SmallVector.h> - -#include <vector> - -namespace ClangBackEnd { - -class FindNamedDeclarationASTVisitor : public clang::RecursiveASTVisitor<FindNamedDeclarationASTVisitor> -{ -public: - explicit FindNamedDeclarationASTVisitor(const clang::SourceManager &sourceManager, - const clang::SourceLocation cursorSourceLocation) - : m_sourceManager(sourceManager), - m_cursorSourceLocation(cursorSourceLocation) - { - } - - bool shouldVisitTemplateInstantiations() const - { - return true; - } - - bool VisitNamedDecl(const clang::NamedDecl *declaration) - { - auto name = declaration->getNameAsString(); - - setResultIfCursorIsInBetween(declaration, - declaration->getLocation(), - declaration->getNameAsString().length()); - - return true; - } - - bool VisitDeclRefExpr(const clang::DeclRefExpr *expression) - { - if (!iterateNestedNameSpecifierLocation(expression->getQualifierLoc())) - return false; - - const auto *declaration = expression->getFoundDecl(); - return setResultIfCursorIsInBetween(declaration, - expression->getLocation(), - declaration->getNameAsString().length()); - } - - bool VisitMemberExpr(const clang::MemberExpr *expression) - { - const auto *declaration = expression->getFoundDecl().getDecl(); - return setResultIfCursorIsInBetween(declaration, - expression->getMemberLoc(), - declaration->getNameAsString().length()); - } - - std::vector<const clang::NamedDecl*> takeNamedDecl() - { - return std::move(m_namedDeclarations); - } - -private: - bool canSetResult(const clang::NamedDecl *declaration, - clang::SourceLocation location) - { - return declaration - && !setResultIfCursorIsInBetween(declaration, - location, - declaration->getNameAsString().length()); - } - - bool iterateNestedNameSpecifierLocation(clang::NestedNameSpecifierLoc nameLocation) { - while (nameLocation) { - const auto *declaration = nameLocation.getNestedNameSpecifier()->getAsNamespace(); - if (canSetResult(declaration, nameLocation.getLocalBeginLoc())) - return false; - - nameLocation = nameLocation.getPrefix(); - } - - return true; - } - - bool isValidLocationWithCursorInside(clang::SourceLocation startLocation, - clang::SourceLocation endLocation) - { - return startLocation.isValid() - && startLocation.isFileID() - && endLocation.isValid() - && endLocation.isFileID() - && isCursorLocationBetween(startLocation, endLocation); - } - - bool setResultIfCursorIsInBetween(const clang::NamedDecl *declaration, - clang::SourceLocation startLocation, - clang::SourceLocation endLocation) - { - bool isValid = isValidLocationWithCursorInside(startLocation, endLocation); - - if (isValid) - m_namedDeclarations.push_back(declaration); - - return !isValid; - } - - bool setResultIfCursorIsInBetween(const clang::NamedDecl *declaration, - clang::SourceLocation location, - uint offset) { - return offset == 0 - || setResultIfCursorIsInBetween(declaration, location, location.getLocWithOffset(offset - 1)); - } - - bool isCursorLocationBetween(const clang::SourceLocation startLocation, - const clang::SourceLocation endLocation) - { - return m_cursorSourceLocation == startLocation - || m_cursorSourceLocation == endLocation - || (m_sourceManager.isBeforeInTranslationUnit(startLocation, m_cursorSourceLocation) - && m_sourceManager.isBeforeInTranslationUnit(m_cursorSourceLocation, endLocation)); - } - - std::vector<const clang::NamedDecl*> m_namedDeclarations; - const clang::SourceManager &m_sourceManager; - const clang::SourceLocation m_cursorSourceLocation; -}; - -inline -std::vector<const clang::NamedDecl *> namedDeclarationsAt(const clang::ASTContext &Context, - const clang::SourceLocation cursorSourceLocation) -{ - const auto &sourceManager = Context.getSourceManager(); - const auto currentFile = sourceManager.getFilename(cursorSourceLocation); - - FindNamedDeclarationASTVisitor visitor(sourceManager, cursorSourceLocation); - - auto declarations = Context.getTranslationUnitDecl()->decls(); - for (auto ¤tDeclation : declarations) { - const auto &fileLocation = currentDeclation->getBeginLoc(); - const auto &fileName = sourceManager.getFilename(fileLocation); - if (fileName == currentFile) { - visitor.TraverseDecl(currentDeclation); - const auto &namedDeclarations = visitor.takeNamedDecl(); - - if (!namedDeclarations.empty()) - return namedDeclarations; - } - } - - return std::vector<const clang::NamedDecl *>(); -} - -inline -USRName USROfDeclaration(const clang::Decl *declaration) -{ - USRName buffer; - - if (declaration == nullptr || clang::index::generateUSRForDecl(declaration, buffer)) - return buffer; - - return buffer; -} - -} // namespace ClangBackend diff --git a/src/tools/clangrefactoringbackend/source/findlocationsofusrs.h b/src/tools/clangrefactoringbackend/source/findlocationsofusrs.h deleted file mode 100644 index b6662205da..0000000000 --- a/src/tools/clangrefactoringbackend/source/findlocationsofusrs.h +++ /dev/null @@ -1,126 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt Creator. -** -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -****************************************************************************/ - -#pragma once - -#include "findcursorusr.h" - -#include <clang/AST/ASTContext.h> -#include <clang/AST/RecursiveASTVisitor.h> -#include <clang/Basic/SourceLocation.h> -#include <clang/Index/USRGeneration.h> -#include <llvm/ADT/SmallVector.h> - -#include <vector> - -namespace ClangBackEnd { - -class FindLocationsOfUSRsASTVisitor : public clang::RecursiveASTVisitor<FindLocationsOfUSRsASTVisitor> -{ -public: - explicit FindLocationsOfUSRsASTVisitor(const std::vector<USRName> &unifiedSymbolResolutions) - : unifiedSymbolResolutions(unifiedSymbolResolutions) - { - } - - bool VisitNamedDecl(const clang::NamedDecl *declaration) { - auto declarationUSR = USROfDeclaration(declaration); - - if (containsUSR(declarationUSR)) - foundLocations.push_back(declaration->getLocation()); - - return true; - } - - bool VisitDeclRefExpr(const clang::DeclRefExpr *expression) { - const auto *declaration = expression->getFoundDecl(); - - iterateNestedNameSpecifierLocation(expression->getQualifierLoc()); - auto declarationUSR = USROfDeclaration(declaration); - - if (containsUSR(declarationUSR)) - foundLocations.push_back(expression->getLocation()); - - return true; - } - - bool VisitMemberExpr(const clang::MemberExpr *expression) { - const auto *declaration = expression->getFoundDecl().getDecl(); - auto declarationUSR = USROfDeclaration(declaration); - - if (containsUSR(declarationUSR)) - foundLocations.push_back(expression->getMemberLoc()); - - return true; - } - - bool shouldVisitTemplateInstantiations() const - { - return true; - } - - std::vector<clang::SourceLocation> takeFoundLocations() const { - return std::move(foundLocations); - } - -private: - void iterateNestedNameSpecifierLocation(clang::NestedNameSpecifierLoc nameLocation) { - while (nameLocation) { - const auto *declaration = nameLocation.getNestedNameSpecifier()->getAsNamespace(); - if (declaration && containsUSR(USROfDeclaration(declaration))) - foundLocations.push_back(nameLocation.getLocalBeginLoc()); - - nameLocation = nameLocation.getPrefix(); - } - } - - bool containsUSR(const USRName &unifiedSymbolResolution) - { - auto found = std::find(unifiedSymbolResolutions.cbegin(), - unifiedSymbolResolutions.cend(), - unifiedSymbolResolution); - - return found != unifiedSymbolResolutions.cend(); - } - -private: - - // All the locations of the USR were found. - const std::vector<USRName> unifiedSymbolResolutions; - std::vector<clang::SourceLocation> foundLocations; -}; - -inline -std::vector<clang::SourceLocation> takeLocationsOfUSRs(std::vector<USRName> &unifiedSymbolResolutions, - clang::Decl *declartation) -{ - FindLocationsOfUSRsASTVisitor visitor(unifiedSymbolResolutions); - - visitor.TraverseDecl(declartation); - - return visitor.takeFoundLocations(); -} - -} // namespace ClangBackend diff --git a/src/tools/clangrefactoringbackend/source/findusrforcursoraction.cpp b/src/tools/clangrefactoringbackend/source/findusrforcursoraction.cpp deleted file mode 100644 index 6fa964f531..0000000000 --- a/src/tools/clangrefactoringbackend/source/findusrforcursoraction.cpp +++ /dev/null @@ -1,128 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt Creator. -** -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -****************************************************************************/ - -#include "findusrforcursoraction.h" - -#include "findcursorusr.h" - -#include <clang/AST/AST.h> -#include <clang/AST/ASTConsumer.h> -#include <clang/AST/ASTContext.h> - -#include <algorithm> -#include <vector> - -namespace ClangBackEnd { - -namespace { - -std::vector<USRName> collectConstructorUnifiedSymbolResolutions(const clang::CXXRecordDecl *declarations) -{ - std::vector<USRName> unifiedSymbolResolutions; - - const auto constructorDeclarations = declarations->getDefinition()->ctors(); - - std::transform(constructorDeclarations.begin(), - constructorDeclarations.end(), - std::back_inserter(unifiedSymbolResolutions), - USROfDeclaration); - - return unifiedSymbolResolutions; -} - -void addUnifiedSymbolResolutionsForDeclaration(const std::vector<const clang::NamedDecl *> &declarations, - std::vector<USRName> &usrs) -{ - - std::transform(declarations.begin(), - declarations.end(), - std::back_inserter(usrs), - [&] (const clang::NamedDecl *declaration) { - return USROfDeclaration(declaration); - }); -} - -} - -class FindDeclarationsConsumer : public clang::ASTConsumer -{ -public: - FindDeclarationsConsumer(Utils::SmallString &symbolName, - std::vector<USRName> &unifiedSymbolResolutions, - uint line, - uint column) - : m_symbolName(symbolName), - m_unifiedSymbolResolutions(unifiedSymbolResolutions), - m_line(line), - m_column(column) - { - } - - void HandleTranslationUnit(clang::ASTContext &astContext) override { - const auto &sourceManager = astContext.getSourceManager(); - const auto cursorSourceLocation = sourceManager.translateLineCol(sourceManager.getMainFileID(), - m_line, - m_column); - - if (cursorSourceLocation.isValid()) - collectUnifiedSymbolResoltions(astContext, cursorSourceLocation); - } - - void collectUnifiedSymbolResoltions(clang::ASTContext &astContext, - const clang::SourceLocation &cursorSourceLocation) - { - const auto foundDeclarations = namedDeclarationsAt(astContext, cursorSourceLocation); - - if (!foundDeclarations.empty()) { - const auto firstFoundDeclaration = foundDeclarations.front(); - - if (const auto *constructorDecl = clang::dyn_cast<clang::CXXConstructorDecl>(firstFoundDeclaration)) { - const clang::CXXRecordDecl *foundDeclarationParent = constructorDecl->getParent(); - m_unifiedSymbolResolutions = collectConstructorUnifiedSymbolResolutions(foundDeclarationParent); - } else if (const auto *destructorDecl = clang::dyn_cast<clang::CXXDestructorDecl>(firstFoundDeclaration)) { - const clang::CXXRecordDecl *foundDeclarationParent = destructorDecl->getParent(); - m_unifiedSymbolResolutions = collectConstructorUnifiedSymbolResolutions(foundDeclarationParent); - } else if (const auto *recordDeclaration = clang::dyn_cast<clang::CXXRecordDecl>(firstFoundDeclaration)) { - m_unifiedSymbolResolutions = collectConstructorUnifiedSymbolResolutions(recordDeclaration); - } - - addUnifiedSymbolResolutionsForDeclaration(foundDeclarations, m_unifiedSymbolResolutions); - m_symbolName = firstFoundDeclaration->getNameAsString(); - } - } - -private: - Utils::SmallString &m_symbolName; - std::vector<USRName> &m_unifiedSymbolResolutions; - uint m_line; - uint m_column; -}; - -std::unique_ptr<clang::ASTConsumer> -USRFindingAction::newASTConsumer() { - return std::make_unique<FindDeclarationsConsumer>(m_symbolName, m_unifiedSymbolResolutions, m_line, m_column); -} - -} // namespace ClangBackEnd diff --git a/src/tools/clangrefactoringbackend/source/findusrforcursoraction.h b/src/tools/clangrefactoringbackend/source/findusrforcursoraction.h deleted file mode 100644 index bfa4a373a4..0000000000 --- a/src/tools/clangrefactoringbackend/source/findusrforcursoraction.h +++ /dev/null @@ -1,70 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt Creator. -** -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -****************************************************************************/ - -#pragma once - -#include "clangrefactoringbackend_global.h" - -#include <utils/smallstring.h> - -#include <clang/Frontend/FrontendAction.h> - -namespace clang { -class ASTConsumer; -class CompilerInstance; -class NamedDecl; -} - -namespace ClangBackEnd { - -class USRFindingAction -{ -public: - USRFindingAction(uint line, uint column) - : m_line(line), - m_column(column) - { - } - - std::unique_ptr<clang::ASTConsumer> newASTConsumer(); - - std::string takeSymbolName() - { - return std::string(m_symbolName); - } - - std::vector<USRName> takeUnifiedSymbolResolutions() - { - return std::move(m_unifiedSymbolResolutions); - } - -private: - Utils::SmallString m_symbolName; - std::vector<USRName> m_unifiedSymbolResolutions; - uint m_line; - uint m_column; -}; - -} // namespace ClangBackEnd diff --git a/src/tools/clangrefactoringbackend/source/refactoringserver.cpp b/src/tools/clangrefactoringbackend/source/refactoringserver.cpp index 83aa5a31fd..387f850c0f 100644 --- a/src/tools/clangrefactoringbackend/source/refactoringserver.cpp +++ b/src/tools/clangrefactoringbackend/source/refactoringserver.cpp @@ -25,7 +25,6 @@ #include "refactoringserver.h" -#include "symbolfinder.h" #include "clangquery.h" #include "symbolindexing.h" @@ -58,21 +57,6 @@ void RefactoringServer::end() QCoreApplication::exit(); } -void RefactoringServer::requestSourceLocationsForRenamingMessage(RequestSourceLocationsForRenamingMessage &&message) -{ - SymbolFinder symbolFinder(message.line, message.column, m_filePathCache); - - symbolFinder.addFile(std::move(message.filePath), - std::move(message.unsavedContent), - std::move(message.commandLine)); - - symbolFinder.findSymbol(); - - client()->sourceLocationsForRenamingMessage({symbolFinder.takeSymbolName(), - symbolFinder.takeSourceLocations(), - message.textDocumentRevision}); -} - void RefactoringServer::requestSourceRangesAndDiagnosticsForQueryMessage( RequestSourceRangesAndDiagnosticsForQueryMessage &&message) { diff --git a/src/tools/clangrefactoringbackend/source/refactoringserver.h b/src/tools/clangrefactoringbackend/source/refactoringserver.h index 75b161f1ab..7934790518 100644 --- a/src/tools/clangrefactoringbackend/source/refactoringserver.h +++ b/src/tools/clangrefactoringbackend/source/refactoringserver.h @@ -60,7 +60,6 @@ public: GeneratedFiles &generatedFiles); void end() override; - void requestSourceLocationsForRenamingMessage(RequestSourceLocationsForRenamingMessage &&message) override; void requestSourceRangesAndDiagnosticsForQueryMessage(RequestSourceRangesAndDiagnosticsForQueryMessage &&message) override; void requestSourceRangesForQueryMessage(RequestSourceRangesForQueryMessage &&message) override; void updateProjectParts(UpdateProjectPartsMessage &&message) override; diff --git a/src/tools/clangrefactoringbackend/source/symbolfinder.cpp b/src/tools/clangrefactoringbackend/source/symbolfinder.cpp deleted file mode 100644 index 8f002f10a1..0000000000 --- a/src/tools/clangrefactoringbackend/source/symbolfinder.cpp +++ /dev/null @@ -1,79 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt Creator. -** -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -****************************************************************************/ - -#include "symbolfinder.h" - -#include "locationsourcefilecallbacks.h" -#include "symbollocationfinderaction.h" - -namespace ClangBackEnd { - -SymbolFinder::SymbolFinder(uint line, uint column, FilePathCachingInterface &filePathCache) - : m_usrFindingAction(line, column), - m_symbolLocationFinderAction(filePathCache), - m_sourceFileCallbacks(line, column, filePathCache) -{ -} - -void SymbolFinder::findSymbol() -{ - clang::tooling::ClangTool tool = createTool(); - - tool.run(clang::tooling::newFrontendActionFactory(&m_usrFindingAction, &m_sourceFileCallbacks).get()); - - if (m_sourceFileCallbacks.hasSourceLocations()) { - m_sourceLocations_ = m_sourceFileCallbacks.takeSourceLocations(); - m_symbolName = m_sourceFileCallbacks.takeSymbolName(); - } else { - m_symbolLocationFinderAction.setUnifiedSymbolResolutions(m_usrFindingAction.takeUnifiedSymbolResolutions()); - - tool.run(clang::tooling::newFrontendActionFactory(&m_symbolLocationFinderAction).get()); - - m_sourceLocations_ = m_symbolLocationFinderAction.takeSourceLocations(); - m_symbolName = m_usrFindingAction.takeSymbolName(); - } -} - -Utils::SmallString SymbolFinder::takeSymbolName() -{ - return std::move(m_symbolName); -} - -const std::vector<USRName> &SymbolFinder::unifiedSymbolResolutions() -{ - return m_symbolLocationFinderAction.unifiedSymbolResolutions(); -} - -const SourceLocationsContainer &SymbolFinder::sourceLocations() const -{ - return m_sourceLocations_; -} - -SourceLocationsContainer SymbolFinder::takeSourceLocations() -{ - return std::move(m_sourceLocations_); -} - -} // namespace ClangBackEnd diff --git a/src/tools/clangrefactoringbackend/source/symbolfinder.h b/src/tools/clangrefactoringbackend/source/symbolfinder.h deleted file mode 100644 index a3c9659032..0000000000 --- a/src/tools/clangrefactoringbackend/source/symbolfinder.h +++ /dev/null @@ -1,58 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt Creator. -** -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -****************************************************************************/ - -#pragma once - -#include "clangtool.h" -#include "findusrforcursoraction.h" -#include "symbollocationfinderaction.h" -#include "locationsourcefilecallbacks.h" - -#include <filepathcachingfwd.h> -#include <sourcelocationscontainer.h> - -namespace ClangBackEnd { - -class SymbolFinder : public ClangTool -{ -public: - SymbolFinder(uint line, uint column, FilePathCachingInterface &filePathCache); - - void findSymbol(); - - Utils::SmallString takeSymbolName(); - const std::vector<USRName> &unifiedSymbolResolutions(); - const SourceLocationsContainer &sourceLocations() const; - SourceLocationsContainer takeSourceLocations(); - -private: - Utils::SmallString m_symbolName; - USRFindingAction m_usrFindingAction; - SymbolLocationFinderAction m_symbolLocationFinderAction; - LocationSourceFileCallbacks m_sourceFileCallbacks; - ClangBackEnd::SourceLocationsContainer m_sourceLocations_; -}; - -} // namespace ClangBackEnd diff --git a/src/tools/clangrefactoringbackend/source/symbolindexer.cpp b/src/tools/clangrefactoringbackend/source/symbolindexer.cpp index 4f3a6f172f..4d042b3fd3 100644 --- a/src/tools/clangrefactoringbackend/source/symbolindexer.cpp +++ b/src/tools/clangrefactoringbackend/source/symbolindexer.cpp @@ -98,7 +98,7 @@ void SymbolIndexer::updateProjectPart(ProjectPartContainer &&projectPart) std::vector<SymbolIndexerTask> symbolIndexerTask; symbolIndexerTask.reserve(projectPart.sourcePathIds.size()); for (FilePathId sourcePathId : projectPart.sourcePathIds) { - SourceTimeStamps dependentTimeStamps = m_symbolStorage.fetchIncludedIndexingTimeStamps( + SourceTimeStamps dependentTimeStamps = m_buildDependencyStorage.fetchIncludedIndexingTimeStamps( sourcePathId); if (!m_modifiedTimeChecker.isUpToDate(dependentTimeStamps)) { @@ -122,7 +122,8 @@ void SymbolIndexer::updateProjectPart(ProjectPartContainer &&projectPart) auto store = [&] { Sqlite::ImmediateTransaction transaction{m_transactionInterface}; - m_symbolStorage.insertOrUpdateIndexingTimeStamps(symbolsCollector.fileStatuses()); + m_buildDependencyStorage.insertOrUpdateIndexingTimeStamps( + symbolsCollector.fileStatuses()); m_symbolStorage.addSymbolsAndSourceLocations(symbolsCollector.symbols(), symbolsCollector.sourceLocations()); transaction.commit(); @@ -144,28 +145,17 @@ void SymbolIndexer::updateProjectPart(ProjectPartContainer &&projectPart) } } - m_pathWatcher.updateIdPaths( - {{projectPartId, m_buildDependencyStorage.fetchPchSources(projectPartId)}}); + m_pathWatcher.updateIdPaths({{{projectPartId, SourceType::Source}, + m_buildDependencyStorage.fetchPchSources(projectPartId)}}); m_symbolIndexerTaskQueue.addOrUpdateTasks(std::move(symbolIndexerTask)); m_symbolIndexerTaskQueue.processEntries(); } -void SymbolIndexer::pathsWithIdsChanged(const ProjectPartIds &) {} +void SymbolIndexer::pathsWithIdsChanged(const std::vector<IdPaths> &) {} void SymbolIndexer::pathsChanged(const FilePathIds &filePathIds) { m_modifiedTimeChecker.pathsChanged(filePathIds); - - FilePathIds dependentSourcePathIds = m_symbolStorage.fetchDependentSourceIds(filePathIds); - - std::vector<SymbolIndexerTask> symbolIndexerTask; - symbolIndexerTask.reserve(dependentSourcePathIds.size()); - - for (FilePathId dependentSourcePathId : dependentSourcePathIds) - updateChangedPath(dependentSourcePathId, symbolIndexerTask); - - m_symbolIndexerTaskQueue.addOrUpdateTasks(std::move(symbolIndexerTask)); - m_symbolIndexerTaskQueue.processEntries(); } void SymbolIndexer::updateChangedPath(FilePathId filePathId, @@ -182,7 +172,8 @@ void SymbolIndexer::updateChangedPath(FilePathId filePathId, ProjectPartId projectPartId = optionalArtefact->projectPartId; - SourceTimeStamps dependentTimeStamps = m_symbolStorage.fetchIncludedIndexingTimeStamps(filePathId); + SourceTimeStamps dependentTimeStamps = m_buildDependencyStorage.fetchIncludedIndexingTimeStamps( + filePathId); auto indexing = [optionalArtefact = std::move(optionalArtefact), filePathId, @@ -207,7 +198,7 @@ void SymbolIndexer::updateChangedPath(FilePathId filePathId, auto store = [&] { Sqlite::ImmediateTransaction transaction{m_transactionInterface}; - m_symbolStorage.insertOrUpdateIndexingTimeStamps(symbolsCollector.fileStatuses()); + m_buildDependencyStorage.insertOrUpdateIndexingTimeStamps(symbolsCollector.fileStatuses()); m_symbolStorage.addSymbolsAndSourceLocations(symbolsCollector.symbols(), symbolsCollector.sourceLocations()); transaction.commit(); diff --git a/src/tools/clangrefactoringbackend/source/symbolindexer.h b/src/tools/clangrefactoringbackend/source/symbolindexer.h index d969cd8026..67da0c9774 100644 --- a/src/tools/clangrefactoringbackend/source/symbolindexer.h +++ b/src/tools/clangrefactoringbackend/source/symbolindexer.h @@ -60,7 +60,7 @@ public: void updateProjectParts(ProjectPartContainers &&projectParts); void updateProjectPart(ProjectPartContainer &&projectPart); - void pathsWithIdsChanged(const ProjectPartIds &ids) override; + void pathsWithIdsChanged(const std::vector<IdPaths> &idPaths) override; void pathsChanged(const FilePathIds &filePathIds) override; void updateChangedPath(FilePathId filePath, std::vector<SymbolIndexerTask> &symbolIndexerTask); @@ -76,6 +76,9 @@ public: const Utils::optional<ProjectPartArtefact> &optionalArtefact) const; private: + FilePathIds filterProjectPartSources(const FilePathIds &filePathIds) const; + +private: SymbolIndexerTaskQueueInterface &m_symbolIndexerTaskQueue; SymbolStorageInterface &m_symbolStorage; BuildDependenciesStorageInterface &m_buildDependencyStorage; diff --git a/src/tools/clangrefactoringbackend/source/symbollocationfinderaction.cpp b/src/tools/clangrefactoringbackend/source/symbollocationfinderaction.cpp deleted file mode 100644 index eddcf683c7..0000000000 --- a/src/tools/clangrefactoringbackend/source/symbollocationfinderaction.cpp +++ /dev/null @@ -1,99 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt Creator. -** -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -****************************************************************************/ - -#include "symbollocationfinderaction.h" - -#include "sourcelocationsutils.h" -#include "findlocationsofusrs.h" - -#include <filepathcachingfwd.h> - -#include <clang/AST/ASTConsumer.h> -#include <clang/AST/ASTContext.h> - -#include <memory> - -namespace ClangBackEnd { - -class FindingSymbolsASTConsumer : public clang::ASTConsumer -{ -public: - FindingSymbolsASTConsumer(std::vector<USRName> &unifiedSymbolResolutions, - FilePathCachingInterface &filePathCache) - : m_unifiedSymbolResolutions(unifiedSymbolResolutions), - m_filePathCache(filePathCache) - { - } - - void HandleTranslationUnit(clang::ASTContext &context) override - { - std::vector<clang::SourceLocation> sourceLocations; - - - auto &&sourceLocationsOfUsr = takeLocationsOfUSRs(m_unifiedSymbolResolutions, context.getTranslationUnitDecl()); - sourceLocations.insert(sourceLocations.end(), - sourceLocationsOfUsr.begin(), - sourceLocationsOfUsr.end()); - - - std::sort(sourceLocations.begin(), sourceLocations.end()); - auto newEnd = std::unique(sourceLocations.begin(), sourceLocations.end()); - sourceLocations.erase(newEnd, sourceLocations.end()); - - updateSourceLocations(sourceLocations, context.getSourceManager()); - - } - - void updateSourceLocations(const std::vector<clang::SourceLocation> &sourceLocations, - const clang::SourceManager &sourceManager) - { - appendSourceLocationsToSourceLocationsContainer(*m_sourceLocationsContainer, - sourceLocations, - sourceManager, - m_filePathCache); - } - - void setSourceLocations(ClangBackEnd::SourceLocationsContainer *sourceLocations) - { - m_sourceLocationsContainer = sourceLocations; - } - -private: - ClangBackEnd::SourceLocationsContainer *m_sourceLocationsContainer = nullptr; - std::vector<USRName> &m_unifiedSymbolResolutions; - FilePathCachingInterface &m_filePathCache; -}; - -std::unique_ptr<clang::ASTConsumer> SymbolLocationFinderAction::newASTConsumer() -{ - auto consumer = std::make_unique<FindingSymbolsASTConsumer>(m_unifiedSymbolResolutions_, - m_filePathCache); - - consumer->setSourceLocations(&m_sourceLocations); - - return consumer; -} - -} // namespace ClangBackEnd diff --git a/src/tools/clangrefactoringbackend/source/symbollocationfinderaction.h b/src/tools/clangrefactoringbackend/source/symbollocationfinderaction.h deleted file mode 100644 index e3f4c4a2f3..0000000000 --- a/src/tools/clangrefactoringbackend/source/symbollocationfinderaction.h +++ /dev/null @@ -1,71 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt Creator. -** -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -****************************************************************************/ - -#pragma once - -#include "clangrefactoringbackend_global.h" - -#include <filepathcachingfwd.h> -#include <sourcelocationscontainer.h> - -#include <clang/Tooling/Refactoring.h> - -namespace clang { -class ASTConsumer; -} - -namespace ClangBackEnd { - -class SymbolLocationFinderAction -{ -public: - SymbolLocationFinderAction(FilePathCachingInterface &filePathCache) - : m_filePathCache(filePathCache) - {} - - std::unique_ptr<clang::ASTConsumer> newASTConsumer(); - - SourceLocationsContainer takeSourceLocations() - { - return std::move(m_sourceLocations); - } - - void setUnifiedSymbolResolutions(std::vector<USRName> &&unifiedSymbolResolutions) - { - m_unifiedSymbolResolutions_ = std::move(unifiedSymbolResolutions); - } - - const std::vector<USRName> &unifiedSymbolResolutions() const - { - return m_unifiedSymbolResolutions_; - } - -private: - ClangBackEnd::SourceLocationsContainer m_sourceLocations; - std::vector<USRName> m_unifiedSymbolResolutions_; - FilePathCachingInterface &m_filePathCache; -}; - -} // namespace ClangBackEnd diff --git a/src/tools/clangrefactoringbackend/source/symbolstorage.h b/src/tools/clangrefactoringbackend/source/symbolstorage.h index 3d7d4c9784..cf7d64e800 100644 --- a/src/tools/clangrefactoringbackend/source/symbolstorage.h +++ b/src/tools/clangrefactoringbackend/source/symbolstorage.h @@ -70,93 +70,6 @@ public: deleteNewLocationsTable(); } - void insertOrUpdateIndexingTimeStamps(const FilePathIds &filePathIds, TimeStamp indexingTimeStamp) override - { - try { - Sqlite::ImmediateTransaction transaction{database}; - - for (FilePathId filePathId : filePathIds) { - inserOrUpdateIndexingTimesStampStatement.write(filePathId.filePathId, - indexingTimeStamp.value); - } - - transaction.commit(); - } catch (const Sqlite::StatementIsBusy &) { - insertOrUpdateIndexingTimeStamps(filePathIds, indexingTimeStamp); - } - } - - void insertOrUpdateIndexingTimeStamps(const FileStatuses &fileStatuses) override - { - for (FileStatus fileStatus : fileStatuses) { - inserOrUpdateIndexingTimesStampStatement.write(fileStatus.filePathId.filePathId, - fileStatus.lastModified); - } - } - - SourceTimeStamps fetchIndexingTimeStamps() const override - { - try { - Sqlite::DeferredTransaction transaction{database}; - - auto timeStamps = fetchIndexingTimeStampsStatement.template values<SourceTimeStamp, 2>( - 1024); - - transaction.commit(); - - return timeStamps; - } catch (const Sqlite::StatementIsBusy &) { - return fetchIndexingTimeStamps(); - } - } - - SourceTimeStamps fetchIncludedIndexingTimeStamps(FilePathId sourcePathId) const override - { - try { - Sqlite::DeferredTransaction transaction{database}; - - auto timeStamps = fetchIncludedIndexingTimeStampsStatement - .template values<SourceTimeStamp, 2>(1024, sourcePathId.filePathId); - - transaction.commit(); - - return timeStamps; - } catch (const Sqlite::StatementIsBusy &) { - return fetchIncludedIndexingTimeStamps(sourcePathId); - } - } - - FilePathIds fetchDependentSourceIds(const FilePathIds &sourcePathIds) const override - { - try { - FilePathIds dependentSourceIds; - - Sqlite::DeferredTransaction transaction{database}; - - for (FilePathId sourcePathId : sourcePathIds) { - FilePathIds newDependentSourceIds; - newDependentSourceIds.reserve(dependentSourceIds.size() + 1024); - - auto newIds = fetchDependentSourceIdsStatement - .template values<FilePathId>(1024, sourcePathId.filePathId); - - std::set_union(dependentSourceIds.begin(), - dependentSourceIds.end(), - newIds.begin(), - newIds.end(), - std::back_inserter(newDependentSourceIds)); - - dependentSourceIds = std::move(newDependentSourceIds); - } - - transaction.commit(); - - return dependentSourceIds; - } catch (const Sqlite::StatementIsBusy &) { - return fetchDependentSourceIds(sourcePathIds); - } - } - void fillTemporarySymbolsTable(const SymbolEntries &symbolEntries) { WriteStatement &statement = insertSymbolsToNewSymbolsStatement; @@ -278,25 +191,6 @@ public: database}; WriteStatement deleteNewSymbolsTableStatement{"DELETE FROM newSymbols", database}; WriteStatement deleteNewLocationsTableStatement{"DELETE FROM newLocations", database}; - WriteStatement inserOrUpdateIndexingTimesStampStatement{ - "INSERT INTO fileStatuses(sourceId, indexingTimeStamp) VALUES (?001, ?002) ON " - "CONFLICT(sourceId) DO UPDATE SET indexingTimeStamp = ?002", - database}; - mutable ReadStatement fetchIncludedIndexingTimeStampsStatement{ - "WITH RECURSIVE collectedDependencies(sourceId) AS (VALUES(?) UNION SELECT " - "dependencySourceId FROM sourceDependencies, collectedDependencies WHERE " - "sourceDependencies.sourceId == collectedDependencies.sourceId) SELECT DISTINCT sourceId, " - "indexingTimeStamp FROM collectedDependencies NATURAL JOIN fileStatuses ORDER BY sourceId", - database}; - mutable ReadStatement fetchIndexingTimeStampsStatement{ - "SELECT sourceId, indexingTimeStamp FROM fileStatuses", database}; - mutable ReadStatement fetchDependentSourceIdsStatement{ - "WITH RECURSIVE collectedDependencies(sourceId) AS (VALUES(?) UNION SELECT " - "sourceDependencies.sourceId FROM sourceDependencies, collectedDependencies WHERE " - "sourceDependencies.dependencySourceId == collectedDependencies.sourceId) SELECT sourceId " - "FROM collectedDependencies WHERE sourceId NOT IN (SELECT dependencySourceId FROM " - "sourceDependencies) ORDER BY sourceId", - database}; }; } // namespace ClangBackEnd diff --git a/src/tools/clangrefactoringbackend/source/symbolstorageinterface.h b/src/tools/clangrefactoringbackend/source/symbolstorageinterface.h index d3c8035e8c..1d0328e9f8 100644 --- a/src/tools/clangrefactoringbackend/source/symbolstorageinterface.h +++ b/src/tools/clangrefactoringbackend/source/symbolstorageinterface.h @@ -48,11 +48,6 @@ public: virtual void addSymbolsAndSourceLocations(const SymbolEntries &symbolEntries, const SourceLocationEntries &sourceLocations) = 0; - virtual void insertOrUpdateIndexingTimeStamps(const FilePathIds &filePathIds, TimeStamp indexingTimeStamp) = 0; - virtual void insertOrUpdateIndexingTimeStamps(const FileStatuses &fileStatuses) = 0; - virtual SourceTimeStamps fetchIndexingTimeStamps() const = 0; - virtual SourceTimeStamps fetchIncludedIndexingTimeStamps(FilePathId sourcePathId) const = 0; - virtual FilePathIds fetchDependentSourceIds(const FilePathIds &sourcePathIds) const = 0; protected: ~SymbolStorageInterface() = default; diff --git a/tests/auto/debugger/tst_dumpers.cpp b/tests/auto/debugger/tst_dumpers.cpp index e5f48e081c..c5ea305470 100644 --- a/tests/auto/debugger/tst_dumpers.cpp +++ b/tests/auto/debugger/tst_dumpers.cpp @@ -2064,10 +2064,10 @@ void tst_Dumpers::dumper_data() + Check("dir", quoted(tempDir), "@QDir") // + Check("dir.canonicalPath", quoted(tempDir), "@QString") + Check("dir.absolutePath", quoted(tempDir), "@QString") % Optional() - + Check("dir.entryInfoList.0", "[0]", quoted(tempDir + "/."), "@QFileInfo") - + Check("dir.entryInfoList.1", "[1]", quoted(tempDir + "/.."), "@QFileInfo") - + Check("dir.entryList.0", "[0]", "\".\"", "@QString") - + Check("dir.entryList.1", "[1]", "\"..\"", "@QString"); + + Check("dir.entryInfoList.0", "[0]", quoted(tempDir + "/."), "@QFileInfo") % NoCdbEngine + + Check("dir.entryInfoList.1", "[1]", quoted(tempDir + "/.."), "@QFileInfo") % NoCdbEngine + + Check("dir.entryList.0", "[0]", "\".\"", "@QString") % NoCdbEngine + + Check("dir.entryList.1", "[1]", "\"..\"", "@QString") % NoCdbEngine; QTest::newRow("QFileInfo") @@ -4804,6 +4804,17 @@ void tst_Dumpers::dumper_data() + Check("s3.1.a", "2", "int"); + QTest::newRow("StdBasicString") + << Data("#include <string>\n" + "template<class T>\n" + "class myallocator : public std::allocator<T> {};\n", + "std::basic_string<char, std::char_traits<char>, myallocator<char>> str(\"hello\");\n" + "unused(&str);\n") + + Check("str", "\"hello\"", "std::basic_string<char, std::char_traits<char>, myallocator<char> >") + + Check("str.0", "[0]", "104", "char") // 104: ASCII 'h' + + Check("str.1", "[1]", "101", "char"); // 101: ASCII 'e' + + QTest::newRow("StdString") << Data("#include <string>\n", "std::string str0, str;\n" @@ -4925,7 +4936,9 @@ void tst_Dumpers::dumper_data() QTest::newRow("StdVector") << Data("#include <vector>\n" - "#include <list>\n", + "#include <list>\n" + "template<class T>\n" + "class myallocator : public std::allocator<T> {};\n", "std::vector<double> v0, v1;\n" "v1.push_back(1);\n" @@ -4970,7 +4983,12 @@ void tst_Dumpers::dumper_data() "unused(&b2);\n\n" "std::vector<bool> b3(300);\n" - "unused(&b3);\n") + "unused(&b3);\n" + + "std::vector<bool, myallocator<bool>> b4;\n" + "b4.push_back(true);\n" + "b4.push_back(false);\n" + "unused(&b4);\n") + Check("v0", "<0 items>", "std::vector<double>") + Check("v1", "<3 items>", "std::vector<double>") @@ -5010,8 +5028,11 @@ void tst_Dumpers::dumper_data() + Check("b3", "<300 items>", "std::vector<bool>") + Check("b3.0", "[0]", "0", "bool") - + Check("b3.299", "[299]", "0", "bool"); + + Check("b3.299", "[299]", "0", "bool") + + Check("b4", "<2 items>", "std::vector<bool, myallocator<bool> >") + + Check("b4.0", "[0]", "1", "bool") + + Check("b4.1", "[1]", "0", "bool"); QTest::newRow("StdVectorQt") << Data("#include <vector>\n" + fooData, @@ -6000,14 +6021,15 @@ void tst_Dumpers::dumper_data() + Check("x3", "", "X &"); QTest::newRow("RValueReference") - << Data("", - "struct S { int a = 32; };\n" + << Data("struct S { int a = 32; };", "auto foo = [](int && i, S && s) { BREAK; return i + s.a; };\n" "foo(int(1), S());\n") + Cxx11Profile() + GdbVersion(80200) - + Check("i", "1", "int &&") - + CheckType("s", "S &&") + + Check("i", "1", "int &&") % NoCdbEngine + + Check("i", "1", "int") % CdbEngine + + CheckType("s", "S &&") % NoCdbEngine + + CheckType("s", "S") % CdbEngine + Check("s.a", "32", "int"); QTest::newRow("SSE") diff --git a/tests/auto/languageserverprotocol/tst_languageserverprotocol.cpp b/tests/auto/languageserverprotocol/tst_languageserverprotocol.cpp index daa013b744..8c5e2d7f59 100644 --- a/tests/auto/languageserverprotocol/tst_languageserverprotocol.cpp +++ b/tests/auto/languageserverprotocol/tst_languageserverprotocol.cpp @@ -102,7 +102,7 @@ void tst_LanguageServerProtocol::baseMessageParse_data() << QByteArray() << false // complete << false // valid - << true // errorMessage + << false // errorMessage << defaultCodec << BaseMessage(); @@ -224,7 +224,7 @@ void tst_LanguageServerProtocol::baseMessageParse_data() << QByteArray("foobar") << true // complete << true // valid - << true // errorMessage + << false // errorMessage << defaultCodec << BaseMessage(); @@ -237,7 +237,7 @@ void tst_LanguageServerProtocol::baseMessageParse_data() << QByteArray("foobar") << true // complete << true // valid - << true // errorMessage + << false // errorMessage << defaultCodec << BaseMessage(); diff --git a/tests/system/objects.map b/tests/system/objects.map index c6064297c7..3091c3c2d1 100644 --- a/tests/system/objects.map +++ b/tests/system/objects.map @@ -71,9 +71,9 @@ :FormEditorStack.CheckBox_QCheckBox {container=':*Qt Creator.FormEditorStack_Designer::Internal::FormEditorStack' name='checkBox' text='CheckBox' type='QCheckBox' visible='1'} :FormEditorStack.PushButton_QPushButton {container=':*Qt Creator.FormEditorStack_Designer::Internal::FormEditorStack' name='pushButton' text='PushButton' type='QPushButton' visible='1'} :FormEditorStack.__qt__passive_editor_QLineEdit {container=':*Qt Creator.FormEditorStack_Designer::Internal::FormEditorStack' name='__qt__passive_editor' type='QLineEdit' visible='1'} -:FormEditorStack.centralWidget_QDesignerWidget {container=':*Qt Creator.FormEditorStack_Designer::Internal::FormEditorStack' name='centralWidget' type='QDesignerWidget' visible='1'} +:FormEditorStack.centralWidget_QDesignerWidget {container=':*Qt Creator.FormEditorStack_Designer::Internal::FormEditorStack' name='centralwidget' type='QDesignerWidget' visible='1'} :FormEditorStack.comboBox_QComboBox {container=':*Qt Creator.FormEditorStack_Designer::Internal::FormEditorStack' name='comboBox' type='QComboBox' visible='1'} -:FormEditorStack.menuBar_QDesignerMenuBar {container=':*Qt Creator.FormEditorStack_Designer::Internal::FormEditorStack' name='menuBar' type='QDesignerMenuBar' visible='1'} +:FormEditorStack.menuBar_QDesignerMenuBar {container=':*Qt Creator.FormEditorStack_Designer::Internal::FormEditorStack' name='menubar' type='QDesignerMenuBar' visible='1'} :FormEditorStack_qdesigner_internal::FormWindow {container=':*Qt Creator.FormEditorStack_Designer::Internal::FormEditorStack' type='qdesigner_internal::FormWindow' unnamed='1' visible='1'} :FormEditorStack_qdesigner_internal::PropertyLineEdit {container=':*Qt Creator.FormEditorStack_Designer::Internal::FormEditorStack' type='qdesigner_internal::PropertyLineEdit' unnamed='1' visible='1'} :Git Repository Clone.Cancel_QPushButton {text='Cancel' type='QPushButton' visible='1' window=':New_ProjectExplorer::JsonWizard'} diff --git a/tests/system/suite_tools/tst_designer_edit/test.py b/tests/system/suite_tools/tst_designer_edit/test.py index 3a9a4a0d5a..bcbadd7409 100644 --- a/tests/system/suite_tools/tst_designer_edit/test.py +++ b/tests/system/suite_tools/tst_designer_edit/test.py @@ -152,7 +152,7 @@ def verifyPreview(menuItems, comboItems): prev = "{name='MainWindow' type='QMainWindow' visible='1' windowTitle='MainWindow - [Preview]'}" invokeMenuItem("Tools", "Form Editor", "Preview...") # verify menu - menuBar = waitForObject("{name='menuBar' type='QMenuBar' visible='1' window=%s}" % prev) + menuBar = waitForObject("{name='menubar' type='QMenuBar' visible='1' window=%s}" % prev) menu = None activateItem(menuBar, "SquishTestFile") # known issue for Squish using Qt5 on Mac diff --git a/tests/unit/unittest/builddependenciesstorage-test.cpp b/tests/unit/unittest/builddependenciesstorage-test.cpp index d14b94fe30..56f8b42ac5 100644 --- a/tests/unit/unittest/builddependenciesstorage-test.cpp +++ b/tests/unit/unittest/builddependenciesstorage-test.cpp @@ -28,8 +28,11 @@ #include "mockfilepathcaching.h" #include "mocksqlitedatabase.h" -#include <sqlitedatabase.h> #include <builddependenciesstorage.h> +#include <refactoringdatabaseinitializer.h> +#include <sqlitedatabase.h> +#include <sqlitereadstatement.h> +#include <sqlitewritestatement.h> #include <utils/optional.h> @@ -70,7 +73,12 @@ protected: MockSqliteWriteStatement &updatePchCreationTimeStampStatement = storage.updatePchCreationTimeStampStatement; MockSqliteWriteStatement &deleteAllProjectPartsFilesWithProjectPartNameStatement = storage.deleteAllProjectPartsFilesWithProjectPartNameStatement; - MockSqliteReadStatement &fetchProjectPartsFilesStatement = storage.fetchPchSourcesStatement; + MockSqliteReadStatement &fetchPchSourcesStatement = storage.fetchPchSourcesStatement; + MockSqliteReadStatement &fetchSourcesStatement = storage.fetchSourcesStatement; + MockSqliteWriteStatement &inserOrUpdateIndexingTimesStampStatement = storage.inserOrUpdateIndexingTimesStampStatement; + MockSqliteReadStatement &fetchIndexingTimeStampsStatement = storage.fetchIndexingTimeStampsStatement; + MockSqliteReadStatement &fetchIncludedIndexingTimeStampsStatement = storage.fetchIncludedIndexingTimeStampsStatement; + MockSqliteReadStatement &fetchDependentSourceIdsStatement = storage.fetchDependentSourceIdsStatement; }; TEST_F(BuildDependenciesStorage, ConvertStringsToJson) @@ -233,13 +241,163 @@ TEST_F(BuildDependenciesStorage, FetchUsedMacros) ASSERT_THAT(usedMacros, result); } -TEST_F(BuildDependenciesStorage, FetchSources) +TEST_F(BuildDependenciesStorage, FetchPchSources) { ClangBackEnd::FilePathIds result{3, 5, 7}; - EXPECT_CALL(fetchProjectPartsFilesStatement, valuesReturnFilePathIds(_, 22)).WillOnce(Return(result)); + EXPECT_CALL(fetchPchSourcesStatement, valuesReturnFilePathIds(_, 22)).WillOnce(Return(result)); auto sources = storage.fetchPchSources(22); ASSERT_THAT(sources, result); } + +TEST_F(BuildDependenciesStorage, FetchSources) +{ + ClangBackEnd::FilePathIds result{3, 5, 7}; + EXPECT_CALL(fetchSourcesStatement, valuesReturnFilePathIds(_, 22)).WillOnce(Return(result)); + + auto sources = storage.fetchSources(22); + + ASSERT_THAT(sources, result); +} + +TEST_F(BuildDependenciesStorage, FetchIndexingTimeStampsIsBusy) +{ + InSequence s; + + EXPECT_CALL(mockDatabase, deferredBegin()); + EXPECT_CALL(fetchIndexingTimeStampsStatement, valuesReturnSourceTimeStamps(1024)) + .WillOnce(Throw(Sqlite::StatementIsBusy{""})); + EXPECT_CALL(mockDatabase, rollback()); + EXPECT_CALL(mockDatabase, deferredBegin()); + EXPECT_CALL(fetchIndexingTimeStampsStatement, valuesReturnSourceTimeStamps(1024)); + EXPECT_CALL(mockDatabase, commit()); + + storage.fetchIndexingTimeStamps(); +} + +TEST_F(BuildDependenciesStorage, InsertIndexingTimeStamp) +{ + ClangBackEnd::FileStatuses fileStatuses{{1, 0, 34}, {2, 0, 37}}; + + EXPECT_CALL(inserOrUpdateIndexingTimesStampStatement, write(TypedEq<int>(1), TypedEq<int>(34))); + EXPECT_CALL(inserOrUpdateIndexingTimesStampStatement, write(TypedEq<int>(2), TypedEq<int>(37))); + + storage.insertOrUpdateIndexingTimeStamps(fileStatuses); +} + +TEST_F(BuildDependenciesStorage, InsertIndexingTimeStampsIsBusy) +{ + InSequence s; + + EXPECT_CALL(mockDatabase, immediateBegin()).WillOnce(Throw(Sqlite::StatementIsBusy{""})); + EXPECT_CALL(mockDatabase, immediateBegin()); + EXPECT_CALL(inserOrUpdateIndexingTimesStampStatement, write(TypedEq<int>(1), TypedEq<int>(34))); + EXPECT_CALL(inserOrUpdateIndexingTimesStampStatement, write(TypedEq<int>(2), TypedEq<int>(34))); + EXPECT_CALL(mockDatabase, commit()); + + storage.insertOrUpdateIndexingTimeStamps({1, 2}, 34); +} + +TEST_F(BuildDependenciesStorage, FetchIncludedIndexingTimeStampsIsBusy) +{ + InSequence s; + + EXPECT_CALL(mockDatabase, deferredBegin()); + EXPECT_CALL(fetchIncludedIndexingTimeStampsStatement, + valuesReturnSourceTimeStamps(1024, TypedEq<int>(1))) + .WillOnce(Throw(Sqlite::StatementIsBusy{""})); + EXPECT_CALL(mockDatabase, rollback()); + EXPECT_CALL(mockDatabase, deferredBegin()); + EXPECT_CALL(fetchIncludedIndexingTimeStampsStatement, + valuesReturnSourceTimeStamps(1024, TypedEq<int>(1))); + EXPECT_CALL(mockDatabase, commit()); + + storage.fetchIncludedIndexingTimeStamps(1); +} + +TEST_F(BuildDependenciesStorage, FetchDependentSourceIdsIsBusy) +{ + InSequence s; + + EXPECT_CALL(mockDatabase, deferredBegin()); + EXPECT_CALL(fetchDependentSourceIdsStatement, valuesReturnFilePathIds(1024, TypedEq<int>(3))); + EXPECT_CALL(fetchDependentSourceIdsStatement, valuesReturnFilePathIds(1024, TypedEq<int>(2))) + .WillOnce(Throw(Sqlite::StatementIsBusy{""})); + EXPECT_CALL(mockDatabase, rollback()); + EXPECT_CALL(mockDatabase, deferredBegin()); + EXPECT_CALL(fetchDependentSourceIdsStatement, valuesReturnFilePathIds(1024, TypedEq<int>(3))); + EXPECT_CALL(fetchDependentSourceIdsStatement, valuesReturnFilePathIds(1024, TypedEq<int>(2))); + EXPECT_CALL(fetchDependentSourceIdsStatement, valuesReturnFilePathIds(1024, TypedEq<int>(7))); + EXPECT_CALL(mockDatabase, commit()); + + storage.fetchDependentSourceIds({3, 2, 7}); +} + +class BuildDependenciesStorageSlow : public testing::Test +{ +protected: + Sqlite::Database database{":memory:", Sqlite::JournalMode::Memory}; + ClangBackEnd::RefactoringDatabaseInitializer<Sqlite::Database> databaseInitializer{database}; + ClangBackEnd::BuildDependenciesStorage<> storage{database}; +}; + +TEST_F(BuildDependenciesStorageSlow, InsertIndexingTimeStamps) +{ + storage.insertOrUpdateIndexingTimeStamps({1, 2}, 34); + + ASSERT_THAT(storage.fetchIndexingTimeStamps(), + ElementsAre(SourceTimeStamp{1, 34}, SourceTimeStamp{2, 34})); +} + +TEST_F(BuildDependenciesStorageSlow, UpdateIndexingTimeStamps) +{ + storage.insertOrUpdateIndexingTimeStamps({1, 2}, 34); + + storage.insertOrUpdateIndexingTimeStamps({1}, 37); + + ASSERT_THAT(storage.fetchIndexingTimeStamps(), + ElementsAre(SourceTimeStamp{1, 37}, SourceTimeStamp{2, 34})); +} + +TEST_F(BuildDependenciesStorageSlow, InsertIndexingTimeStamp) +{ + storage.insertOrUpdateIndexingTimeStamps({{1, 0, 34}, {2, 0, 37}}); + + ASSERT_THAT(storage.fetchIndexingTimeStamps(), + ElementsAre(SourceTimeStamp{1, 34}, SourceTimeStamp{2, 37})); +} + +TEST_F(BuildDependenciesStorageSlow, UpdateIndexingTimeStamp) +{ + storage.insertOrUpdateIndexingTimeStamps({{1, 0, 34}, {2, 0, 34}}); + + storage.insertOrUpdateIndexingTimeStamps({{2, 0, 37}}); + + ASSERT_THAT(storage.fetchIndexingTimeStamps(), + ElementsAre(SourceTimeStamp{1, 34}, SourceTimeStamp{2, 37})); +} + +TEST_F(BuildDependenciesStorageSlow, FetchIncludedIndexingTimeStamps) +{ + storage.insertOrUpdateIndexingTimeStamps({1, 2, 3, 4, 5}, 34); + storage.insertOrUpdateSourceDependencies({{1, 2}, {1, 3}, {2, 3}, {3, 4}, {5, 3}}); + + auto timeStamps = storage.fetchIncludedIndexingTimeStamps(1); + + ASSERT_THAT(timeStamps, + ElementsAre(SourceTimeStamp{1, 34}, + SourceTimeStamp{2, 34}, + SourceTimeStamp{3, 34}, + SourceTimeStamp{4, 34})); +} + +TEST_F(BuildDependenciesStorageSlow, FetchDependentSourceIds) +{ + storage.insertOrUpdateSourceDependencies({{1, 2}, {1, 3}, {2, 3}, {4, 2}, {5, 6}, {7, 6}}); + + auto sourceIds = storage.fetchDependentSourceIds({3, 2, 7}); + + ASSERT_THAT(sourceIds, ElementsAre(FilePathId{1}, FilePathId{4}, FilePathId{7})); +} } // namespace diff --git a/tests/unit/unittest/clangpathwatcher-test.cpp b/tests/unit/unittest/clangpathwatcher-test.cpp index f4d99e358d..3105000ca1 100644 --- a/tests/unit/unittest/clangpathwatcher-test.cpp +++ b/tests/unit/unittest/clangpathwatcher-test.cpp @@ -48,8 +48,11 @@ using ClangBackEnd::FilePath; using ClangBackEnd::FilePathId; using ClangBackEnd::FilePathIds; using ClangBackEnd::FilePathView; +using ClangBackEnd::IdPaths; +using ClangBackEnd::ProjectChunkId; using ClangBackEnd::ProjectPartId; using ClangBackEnd::ProjectPartIds; +using ClangBackEnd::SourceType; using ClangBackEnd::WatcherEntries; using ClangBackEnd::WatcherEntry; @@ -111,9 +114,9 @@ protected: NiceMock<MockFileSystem> mockFileSystem; Watcher watcher{mockFilePathCache, mockFileSystem, ¬ifier}; NiceMock<MockQFileSytemWatcher> &mockQFileSytemWatcher = watcher.fileSystemWatcher(); - ProjectPartId id1{2}; - ProjectPartId id2{3}; - ProjectPartId id3{4}; + ProjectChunkId id1{2, SourceType::ProjectInclude}; + ProjectChunkId id2{2, SourceType::Source}; + ProjectChunkId id3{4, SourceType::SystemInclude}; FilePathView path1{"/path/path1"}; FilePathView path2{"/path/path2"}; FilePathView path3{"/path2/path1"}; @@ -128,14 +131,15 @@ protected: Utils::PathString directoryPathString2 = directoryPath2; FilePathIds pathIds = {1, 2, 3, 4, 5}; ClangBackEnd::DirectoryPathIds directoryPaths = {1, 2, 3}; - ClangBackEnd::ProjectPartIds ids{id1, id2, id3}; - WatcherEntry watcherEntry1{ids[0], directoryPaths[0], pathIds[0]}; - WatcherEntry watcherEntry2{ids[1], directoryPaths[0], pathIds[0]}; - WatcherEntry watcherEntry3{ids[0], directoryPaths[0], pathIds[1]}; - WatcherEntry watcherEntry4{ids[1], directoryPaths[0], pathIds[1]}; - WatcherEntry watcherEntry5{ids[2], directoryPaths[0], pathIds[1]}; - WatcherEntry watcherEntry6{ids[0], directoryPaths[1], pathIds[2]}; - WatcherEntry watcherEntry7{ids[1], directoryPaths[1], pathIds[3]}; + ClangBackEnd::ProjectChunkIds ids{id1, id2, id3}; + WatcherEntry watcherEntry1{id1, directoryPaths[0], pathIds[0]}; + WatcherEntry watcherEntry2{id2, directoryPaths[0], pathIds[0]}; + WatcherEntry watcherEntry3{id1, directoryPaths[0], pathIds[1]}; + WatcherEntry watcherEntry4{id2, directoryPaths[0], pathIds[1]}; + WatcherEntry watcherEntry5{id3, directoryPaths[0], pathIds[1]}; + WatcherEntry watcherEntry6{id1, directoryPaths[1], pathIds[2]}; + WatcherEntry watcherEntry7{id2, directoryPaths[1], pathIds[3]}; + WatcherEntry watcherEntry8{id3, directoryPaths[1], pathIds[3]}; }; TEST_F(ClangPathWatcher, AddIdPaths) @@ -260,12 +264,13 @@ TEST_F(ClangPathWatcher, DontAddNewEntriesWithDifferentIdAndSamePaths) TEST_F(ClangPathWatcher, RemoveEntriesWithId) { - watcher.updateIdPaths( - {{id1, {pathIds[0], pathIds[1]}}, {id2, {pathIds[0], pathIds[1]}}, {id3, {pathIds[1]}}}); + watcher.updateIdPaths({{id1, {pathIds[0], pathIds[1]}}, + {id2, {pathIds[0], pathIds[1]}}, + {id3, {pathIds[1], pathIds[3]}}}); - watcher.removeIds({id1}); + watcher.removeIds({2}); - ASSERT_THAT(watcher.watchedEntries(), ElementsAre(watcherEntry2, watcherEntry4, watcherEntry5)); + ASSERT_THAT(watcher.watchedEntries(), ElementsAre(watcherEntry5, watcherEntry8)); } TEST_F(ClangPathWatcher, RemoveNoPathsForEmptyIds) @@ -284,28 +289,28 @@ TEST_F(ClangPathWatcher, RemoveNoPathsForOneId) EXPECT_CALL(mockQFileSytemWatcher, removePaths(_)) .Times(0); - watcher.removeIds({id3}); + watcher.removeIds({id3.id}); } TEST_F(ClangPathWatcher, RemovePathForOneId) { watcher.updateIdPaths( - {{id1, {pathIds[0], pathIds[1]}}, {id2, {pathIds[0], pathIds[1], pathIds[3]}}}); + {{id1, {pathIds[0], pathIds[1]}}, {id3, {pathIds[0], pathIds[1], pathIds[3]}}}); EXPECT_CALL(mockQFileSytemWatcher, removePaths(ElementsAre(directoryPath2))); - watcher.removeIds({id2}); + watcher.removeIds({id3.id}); } TEST_F(ClangPathWatcher, RemoveNoPathSecondTime) { watcher.updateIdPaths( {{id1, {pathIds[0], pathIds[1]}}, {id2, {pathIds[0], pathIds[1], pathIds[3]}}}); - watcher.removeIds({id2}); + watcher.removeIds({id2.id}); EXPECT_CALL(mockQFileSytemWatcher, removePaths(_)).Times(0); - watcher.removeIds({id2}); + watcher.removeIds({id2.id}); } TEST_F(ClangPathWatcher, RemoveAllPathsForThreeId) @@ -315,7 +320,7 @@ TEST_F(ClangPathWatcher, RemoveAllPathsForThreeId) EXPECT_CALL(mockQFileSytemWatcher, removePaths(ElementsAre(directoryPath, directoryPath2))); - watcher.removeIds({id1, id2, id3}); + watcher.removeIds({id1.id, id2.id, id3.id}); } TEST_F(ClangPathWatcher, RemoveOnePathForTwoId) @@ -325,7 +330,7 @@ TEST_F(ClangPathWatcher, RemoveOnePathForTwoId) EXPECT_CALL(mockQFileSytemWatcher, removePaths(ElementsAre(directoryPath))); - watcher.removeIds({id1, id2}); + watcher.removeIds({id1.id, id2.id}); } TEST_F(ClangPathWatcher, NotAnymoreWatchedEntriesWithId) @@ -349,13 +354,14 @@ TEST_F(ClangPathWatcher, RemoveUnusedEntries) TEST_F(ClangPathWatcher, TwoNotifyFileChanges) { watcher.updateIdPaths({{id1, {pathIds[0], pathIds[1], pathIds[2]}}, - {id2, {pathIds[0], pathIds[1], pathIds[3]}}, + {id2, {pathIds[0], pathIds[1], pathIds[2], pathIds[3], pathIds[4]}}, {id3, {pathIds[4]}}}); ON_CALL(mockFileSystem, lastModified(Eq(pathIds[0]))).WillByDefault(Return(2)); ON_CALL(mockFileSystem, lastModified(Eq(pathIds[1]))).WillByDefault(Return(2)); ON_CALL(mockFileSystem, lastModified(Eq(pathIds[3]))).WillByDefault(Return(2)); - EXPECT_CALL(notifier, pathsWithIdsChanged(ElementsAre(id1, id2))); + EXPECT_CALL(notifier, + pathsWithIdsChanged(ElementsAre(IdPaths{id1, {1, 2}}, IdPaths{id2, {1, 2, 4}}))); mockQFileSytemWatcher.directoryChanged(directoryPath); mockQFileSytemWatcher.directoryChanged(directoryPath2); diff --git a/tests/unit/unittest/commandlinebuilder-test.cpp b/tests/unit/unittest/commandlinebuilder-test.cpp index c5765037dc..08c4e32f76 100644 --- a/tests/unit/unittest/commandlinebuilder-test.cpp +++ b/tests/unit/unittest/commandlinebuilder-test.cpp @@ -52,8 +52,8 @@ public: CommandLineBuilder() { cppProjectInfo.language = Utils::Language::Cxx; } public: - ClangBackEnd::PchTask emptyProjectInfo{0, {}, {}, {}, {}, {}, {}, {}}; - ClangBackEnd::PchTask cppProjectInfo{1, {}, {}, {}, {}, {}, {}, {}}; + ClangBackEnd::PchTask emptyProjectInfo{0, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}}; + ClangBackEnd::PchTask cppProjectInfo{1, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}}; }; template <> diff --git a/tests/unit/unittest/gtest-creator-printing.cpp b/tests/unit/unittest/gtest-creator-printing.cpp index 0ab962dfa5..737120abb2 100644 --- a/tests/unit/unittest/gtest-creator-printing.cpp +++ b/tests/unit/unittest/gtest-creator-printing.cpp @@ -359,9 +359,8 @@ std::ostream &operator<<(std::ostream &out, const SourceLocationEntry &entry) std::ostream &operator<<(std::ostream &out, const WatcherEntry &entry) { - out << "(" - << entry.id << ", " - << entry.filePathId + out << "(" << entry.directoryPathId << ", " << entry.filePathId << ", " << entry.id << ", " + << entry.lastModified << ", " << ")"; return out; @@ -811,19 +810,6 @@ std::ostream &operator<<(std::ostream &out, const ToolTipInfo &info) return out; } -std::ostream &operator<<(std::ostream &os, const RequestSourceLocationsForRenamingMessage &message) -{ - os << "(" - << message.filePath << ", " - << message.line << ", " - << message.column << ", " - << message.unsavedContent << ", " - << message.commandLine - << ")"; - - return os; -} - std::ostream &operator<<(std::ostream &os, const RequestSourceRangesAndDiagnosticsForQueryMessage &message) { os << "(" @@ -854,17 +840,6 @@ std::ostream &operator<<(std::ostream &os, const SourceLocationContainer &contai return os; } -std::ostream &operator<<(std::ostream &os, const SourceLocationsForRenamingMessage &message) -{ - os << "(" - << message.symbolName << ", " - << message.textDocumentRevision << ", " - << message.sourceLocations - << ")"; - - return os; -} - std::ostream &operator<<(std::ostream &os, const SourceRangeContainer &container) { os << "(" @@ -1290,6 +1265,17 @@ std::ostream &operator<<(std::ostream &out, const PchPaths &pchPaths) { return out << "(" << pchPaths.projectPchPath << ", " << pchPaths.systemPchPath << ")"; } + +std::ostream &operator<<(std::ostream &out, const ProjectChunkId &chunk) +{ + return out << "(" << chunk.id << ", " << typeToString(chunk.sourceType) << ")"; +} + +std::ostream &operator<<(std::ostream &out, const DirectoryPathId &id) +{ + return out << id.directoryPathId; +} + void PrintTo(const FilePath &filePath, ::std::ostream *os) { *os << filePath; diff --git a/tests/unit/unittest/gtest-creator-printing.h b/tests/unit/unittest/gtest-creator-printing.h index b874fc90e4..b533186739 100644 --- a/tests/unit/unittest/gtest-creator-printing.h +++ b/tests/unit/unittest/gtest-creator-printing.h @@ -147,11 +147,9 @@ class RequestAnnotationsMessage; class RequestFollowSymbolMessage; class RequestReferencesMessage; class RequestToolTipMessage; -class RequestSourceLocationsForRenamingMessage; class RequestSourceRangesAndDiagnosticsForQueryMessage; class RequestSourceRangesForQueryMessage; class SourceLocationContainer; -class SourceLocationsForRenamingMessage; class SourceRangeContainer; class SourceRangesAndDiagnosticsForQueryMessage; class SourceRangesContainer; @@ -200,6 +198,8 @@ struct ArgumentsEntry; class ProjectPartContainer; class ProjectPartId; class PchPaths; +class ProjectChunkId; +class DirectoryPathId; std::ostream &operator<<(std::ostream &out, const SourceLocationEntry &entry); std::ostream &operator<<(std::ostream &out, const IdPaths &idPaths); @@ -239,11 +239,10 @@ std::ostream &operator<<(std::ostream &out, const RequestFollowSymbolMessage &me std::ostream &operator<<(std::ostream &out, const RequestReferencesMessage &message); std::ostream &operator<<(std::ostream &out, const RequestToolTipMessage &message); std::ostream &operator<<(std::ostream &out, const ToolTipInfo &info); -std::ostream &operator<<(std::ostream &out, const RequestSourceLocationsForRenamingMessage &message); -std::ostream &operator<<(std::ostream &out, const RequestSourceRangesAndDiagnosticsForQueryMessage &message); +std::ostream &operator<<(std::ostream &out, + const RequestSourceRangesAndDiagnosticsForQueryMessage &message); std::ostream &operator<<(std::ostream &out, const RequestSourceRangesForQueryMessage &message); std::ostream &operator<<(std::ostream &out, const SourceLocationContainer &container); -std::ostream &operator<<(std::ostream &out, const SourceLocationsForRenamingMessage &message); std::ostream &operator<<(std::ostream &out, const SourceRangeContainer &container); std::ostream &operator<<(std::ostream &out, const SourceRangesAndDiagnosticsForQueryMessage &message); std::ostream &operator<<(std::ostream &out, const SourceRangesContainer &container); @@ -293,6 +292,8 @@ std::ostream &operator<<(std::ostream &out, const ArgumentsEntry &entry); std::ostream &operator<<(std::ostream &out, const ProjectPartContainer &container); std::ostream &operator<<(std::ostream &out, const ProjectPartId &projectPathId); std::ostream &operator<<(std::ostream &out, const PchPaths &pchPaths); +std::ostream &operator<<(std::ostream &out, const ProjectChunkId &chunk); +std::ostream &operator<<(std::ostream &out, const DirectoryPathId &id); void PrintTo(const FilePath &filePath, ::std::ostream *os); void PrintTo(const FilePathView &filePathView, ::std::ostream *os); diff --git a/tests/unit/unittest/mockbuilddependenciesstorage.h b/tests/unit/unittest/mockbuilddependenciesstorage.h index dd2850d88c..0436e27f92 100644 --- a/tests/unit/unittest/mockbuilddependenciesstorage.h +++ b/tests/unit/unittest/mockbuilddependenciesstorage.h @@ -53,5 +53,16 @@ public: void(long long pchCreationTimeStamp, ClangBackEnd::ProjectPartId projectPartId)); MOCK_CONST_METHOD1(fetchPchSources, ClangBackEnd::FilePathIds(ClangBackEnd::ProjectPartId projectPartId)); + MOCK_CONST_METHOD1(fetchSources, + ClangBackEnd::FilePathIds(ClangBackEnd::ProjectPartId projectPartId)); + MOCK_METHOD2(insertOrUpdateIndexingTimeStamps, + void(const ClangBackEnd::FilePathIds &filePathIds, + ClangBackEnd::TimeStamp indexingTimeStamp)); + MOCK_METHOD1(insertOrUpdateIndexingTimeStamps, void(const ClangBackEnd::FileStatuses &)); + MOCK_CONST_METHOD0(fetchIndexingTimeStamps, ClangBackEnd::SourceTimeStamps()); + MOCK_CONST_METHOD1(fetchIncludedIndexingTimeStamps, + ClangBackEnd::SourceTimeStamps(ClangBackEnd::FilePathId sourcePathId)); + MOCK_CONST_METHOD1(fetchDependentSourceIds, + ClangBackEnd::FilePathIds(const ClangBackEnd::FilePathIds &sourcePathIds)); }; diff --git a/tests/unit/unittest/mockclangpathwatchernotifier.h b/tests/unit/unittest/mockclangpathwatchernotifier.h index c89f37adaf..8d8b8b1369 100644 --- a/tests/unit/unittest/mockclangpathwatchernotifier.h +++ b/tests/unit/unittest/mockclangpathwatchernotifier.h @@ -32,7 +32,7 @@ class MockClangPathWatcherNotifier : public ClangBackEnd::ClangPathWatcherNotifier { public: - MOCK_METHOD1(pathsWithIdsChanged, void(const ClangBackEnd::ProjectPartIds &ids)); + MOCK_METHOD1(pathsWithIdsChanged, void(const std::vector<ClangBackEnd::IdPaths> &idPaths)); MOCK_METHOD1(pathsChanged, void (const ClangBackEnd::FilePathIds &filePathIds)); diff --git a/tests/unit/unittest/mockpchtaskgenerator.h b/tests/unit/unittest/mockpchtaskgenerator.h index d2573f0c35..492e320a33 100644 --- a/tests/unit/unittest/mockpchtaskgenerator.h +++ b/tests/unit/unittest/mockpchtaskgenerator.h @@ -35,6 +35,9 @@ public: MOCK_METHOD2(addProjectParts, void(const ClangBackEnd::ProjectPartContainers &projectParts, const Utils::SmallStringVector &toolChainArguments)); + MOCK_METHOD2(addNonSystemProjectParts, + void(const ClangBackEnd::ProjectPartContainers &projectParts, + const Utils::SmallStringVector &toolChainArguments)); MOCK_METHOD1(removeProjectParts, void(const ClangBackEnd::ProjectPartIds &projectsPartIds)); void addProjectParts(ClangBackEnd::ProjectPartContainers &&projectParts, @@ -42,4 +45,10 @@ public: { addProjectParts(projectParts, toolChainArguments); } + + void addNonSystemProjectParts(ClangBackEnd::ProjectPartContainers &&projectParts, + Utils::SmallStringVector &&toolChainArguments) override + { + addNonSystemProjectParts(projectParts, toolChainArguments); + } }; diff --git a/tests/unit/unittest/mockrefactoringclient.h b/tests/unit/unittest/mockrefactoringclient.h index 2542898f29..11721bb7af 100644 --- a/tests/unit/unittest/mockrefactoringclient.h +++ b/tests/unit/unittest/mockrefactoringclient.h @@ -34,8 +34,6 @@ class MockRefactoringClient : public ClangBackEnd::RefactoringClientInterface public: MOCK_METHOD0(alive, void()); - MOCK_METHOD1(sourceLocationsForRenamingMessage, - void (const ClangBackEnd::SourceLocationsForRenamingMessage&)); MOCK_METHOD1(sourceRangesAndDiagnosticsForQueryMessage, void (const ClangBackEnd::SourceRangesAndDiagnosticsForQueryMessage&)); MOCK_METHOD1(sourceRangesForQueryMessage, @@ -43,11 +41,6 @@ public: MOCK_METHOD1(progress, void (const ClangBackEnd::ProgressMessage&)); - void sourceLocationsForRenamingMessage(ClangBackEnd::SourceLocationsForRenamingMessage &&message) override - { - sourceLocationsForRenamingMessage(message); - } - void sourceRangesAndDiagnosticsForQueryMessage(ClangBackEnd::SourceRangesAndDiagnosticsForQueryMessage &&message) override { sourceRangesAndDiagnosticsForQueryMessage(message); @@ -58,10 +51,6 @@ public: sourceRangesForQueryMessage(message); } - void setLocalRenamingCallback(RenameCallback &&) override - { - } - void progress(ClangBackEnd::ProgressMessage &&message) override { progress(message); diff --git a/tests/unit/unittest/mockrefactoringserver.h b/tests/unit/unittest/mockrefactoringserver.h index 4bd6aac8fc..dd32a33103 100644 --- a/tests/unit/unittest/mockrefactoringserver.h +++ b/tests/unit/unittest/mockrefactoringserver.h @@ -35,9 +35,6 @@ public: MOCK_METHOD0(end, void()); - MOCK_METHOD1(requestSourceLocationsForRenamingMessage, - void (const ClangBackEnd::RequestSourceLocationsForRenamingMessage&)); - MOCK_METHOD1(requestSourceRangesAndDiagnosticsForQueryMessage, void (const ClangBackEnd::RequestSourceRangesAndDiagnosticsForQueryMessage&)); @@ -62,11 +59,6 @@ public: MOCK_METHOD2(setProgress, void(int, int)); - void requestSourceLocationsForRenamingMessage(ClangBackEnd::RequestSourceLocationsForRenamingMessage &&message) override - { - requestSourceLocationsForRenamingMessage(message); - } - void requestSourceRangesAndDiagnosticsForQueryMessage(ClangBackEnd::RequestSourceRangesAndDiagnosticsForQueryMessage &&message) override { requestSourceRangesAndDiagnosticsForQueryMessage(message); diff --git a/tests/unit/unittest/mocksymbolstorage.h b/tests/unit/unittest/mocksymbolstorage.h index 7b77868e8a..a174389735 100644 --- a/tests/unit/unittest/mocksymbolstorage.h +++ b/tests/unit/unittest/mocksymbolstorage.h @@ -37,11 +37,4 @@ public: MOCK_METHOD2(addSymbolsAndSourceLocations, void(const ClangBackEnd::SymbolEntries &symbolEentries, const ClangBackEnd::SourceLocationEntries &sourceLocations)); - MOCK_METHOD2(insertOrUpdateIndexingTimeStamps, - void(const FilePathIds &filePathIds, ClangBackEnd::TimeStamp indexingTimeStamp)); - MOCK_METHOD1(insertOrUpdateIndexingTimeStamps, void(const ClangBackEnd::FileStatuses &)); - MOCK_CONST_METHOD0(fetchIndexingTimeStamps, ClangBackEnd::SourceTimeStamps()); - MOCK_CONST_METHOD1(fetchIncludedIndexingTimeStamps, - ClangBackEnd::SourceTimeStamps(ClangBackEnd::FilePathId sourcePathId)); - MOCK_CONST_METHOD1(fetchDependentSourceIds, FilePathIds(const FilePathIds &sourcePathIds)); }; diff --git a/tests/unit/unittest/pchcreator-test.cpp b/tests/unit/unittest/pchcreator-test.cpp index 04e198eec7..e6ae4a943d 100644 --- a/tests/unit/unittest/pchcreator-test.cpp +++ b/tests/unit/unittest/pchcreator-test.cpp @@ -34,12 +34,13 @@ #include "mockpchmanagerclient.h" #include "testenvironment.h" -#include <refactoringdatabaseinitializer.h> #include <filepathcaching.h> #include <generatedfiles.h> #include <pchcreator.h> #include <precompiledheadersupdatedmessage.h> #include <progressmessage.h> +#include <refactoringdatabaseinitializer.h> +#include <updateprojectpartsmessage.h> #include <sqlitedatabase.h> @@ -55,12 +56,14 @@ using ClangBackEnd::GeneratedFiles; using ClangBackEnd::IdPaths; using ClangBackEnd::IncludeSearchPathType; using ClangBackEnd::PchTask; +using ClangBackEnd::PrecompiledHeadersUpdatedMessage; +using ClangBackEnd::ProjectChunkId; +using ClangBackEnd::ProjectPartContainer; using ClangBackEnd::ProjectPartPch; using ClangBackEnd::SourceEntries; using ClangBackEnd::SourceEntry; using ClangBackEnd::SourceType; using ClangBackEnd::V2::FileContainer; -using ClangBackEnd::ProjectPartContainer; using Utils::PathString; using Utils::SmallString; @@ -91,6 +94,13 @@ protected: return creator.filePathCache().filePathId(path); } + FilePathIds sorted(FilePathIds &&filePathIds) + { + std::sort(filePathIds.begin(), filePathIds.end()); + + return std::move(filePathIds); + } + protected: Sqlite::Database database{":memory:", Sqlite::JournalMode::Memory}; ClangBackEnd::RefactoringDatabaseInitializer<Sqlite::Database> databaseInitializer{database}; @@ -111,14 +121,19 @@ protected: mockBuildDependenciesStorage}; PchTask pchTask1{ 1, - {id(TESTDATA_DIR "/builddependencycollector/project/header2.h"), - id(TESTDATA_DIR "/builddependencycollector/external/external1.h"), - id(TESTDATA_DIR "/builddependencycollector/external/external2.h")}, - {id(TESTDATA_DIR "/builddependencycollector/project/header2.h"), - id(TESTDATA_DIR "/builddependencycollector/external/external1.h"), - id(TESTDATA_DIR "/builddependencycollector/external/external2.h"), - id(generatedFilePath), - id(main2Path)}, + sorted({id(TESTDATA_DIR "/builddependencycollector/project/header2.h"), + id(TESTDATA_DIR "/builddependencycollector/external/external1.h"), + id(TESTDATA_DIR "/builddependencycollector/external/external2.h")}), + sorted({id(TESTDATA_DIR "/builddependencycollector/system/system1.h"), + id(TESTDATA_DIR "/builddependencycollector/system/system2.h"), + id(generatedFilePath)}), + sorted({id(TESTDATA_DIR "/builddependencycollector/external/external1.h"), + id(TESTDATA_DIR "/builddependencycollector/external/external2.h"), + id(generatedFilePath)}), + sorted({id(TESTDATA_DIR "/builddependencycollector/project/header1.h"), + id(TESTDATA_DIR "/builddependencycollector/project/header2.h"), + id(generatedFilePath)}), + sorted({id(main2Path), id(generatedFilePath)}), {}, {}, {}, @@ -214,14 +229,33 @@ TEST_F(PchCreatorVerySlowTest, SourcesAreWatchedAfterSucess) creator.generatePch(std::move(pchTask1)); EXPECT_CALL(mockClangPathWatcher, + updateIdPaths(ElementsAre( + AllOf(Field(&ClangBackEnd::IdPaths::id, ProjectChunkId{1, SourceType::Source}), + Field(&ClangBackEnd::IdPaths::filePathIds, + UnorderedElementsAre(id(main2Path))))))); + + EXPECT_CALL(mockClangPathWatcher, + updateIdPaths(ElementsAre(AllOf( + Field(&ClangBackEnd::IdPaths::id, ProjectChunkId{1, SourceType::UserInclude}), + Field(&ClangBackEnd::IdPaths::filePathIds, + UnorderedElementsAre( + id(TESTDATA_DIR "/builddependencycollector/project/header1.h"), + id(TESTDATA_DIR "/builddependencycollector/project/header2.h"))))))); + EXPECT_CALL( + mockClangPathWatcher, + updateIdPaths(ElementsAre( + AllOf(Field(&ClangBackEnd::IdPaths::id, ProjectChunkId{1, SourceType::ProjectInclude}), + Field(&ClangBackEnd::IdPaths::filePathIds, + UnorderedElementsAre( + id(TESTDATA_DIR "/builddependencycollector/external/external1.h"), + id(TESTDATA_DIR "/builddependencycollector/external/external2.h"))))))); + EXPECT_CALL(mockClangPathWatcher, updateIdPaths(ElementsAre(AllOf( - Field(&ClangBackEnd::IdPaths::id, 1), + Field(&ClangBackEnd::IdPaths::id, ProjectChunkId{1, SourceType::SystemInclude}), Field(&ClangBackEnd::IdPaths::filePathIds, UnorderedElementsAre( - id(TESTDATA_DIR "/builddependencycollector/project/header2.h"), - id(TESTDATA_DIR "/builddependencycollector/external/external1.h"), - id(TESTDATA_DIR "/builddependencycollector/external/external2.h"), - id(TESTDATA_DIR "/builddependencycollector/project/main2.cpp"))))))); + id(TESTDATA_DIR "/builddependencycollector/system/system1.h"), + id(TESTDATA_DIR "/builddependencycollector/system/system2.h"))))))); creator.doInMainThreadAfterFinished(); } @@ -233,14 +267,33 @@ TEST_F(PchCreatorVerySlowTest, SourcesAreWatchedAfterFail) creator.generatePch(std::move(pchTask1)); EXPECT_CALL(mockClangPathWatcher, + updateIdPaths(ElementsAre( + AllOf(Field(&ClangBackEnd::IdPaths::id, ProjectChunkId{1, SourceType::Source}), + Field(&ClangBackEnd::IdPaths::filePathIds, + UnorderedElementsAre(id(main2Path))))))); + + EXPECT_CALL(mockClangPathWatcher, + updateIdPaths(ElementsAre(AllOf( + Field(&ClangBackEnd::IdPaths::id, ProjectChunkId{1, SourceType::UserInclude}), + Field(&ClangBackEnd::IdPaths::filePathIds, + UnorderedElementsAre( + id(TESTDATA_DIR "/builddependencycollector/project/header1.h"), + id(TESTDATA_DIR "/builddependencycollector/project/header2.h"))))))); + EXPECT_CALL( + mockClangPathWatcher, + updateIdPaths(ElementsAre( + AllOf(Field(&ClangBackEnd::IdPaths::id, ProjectChunkId{1, SourceType::ProjectInclude}), + Field(&ClangBackEnd::IdPaths::filePathIds, + UnorderedElementsAre( + id(TESTDATA_DIR "/builddependencycollector/external/external1.h"), + id(TESTDATA_DIR "/builddependencycollector/external/external2.h"))))))); + EXPECT_CALL(mockClangPathWatcher, updateIdPaths(ElementsAre(AllOf( - Field(&ClangBackEnd::IdPaths::id, 1), + Field(&ClangBackEnd::IdPaths::id, ProjectChunkId{1, SourceType::SystemInclude}), Field(&ClangBackEnd::IdPaths::filePathIds, UnorderedElementsAre( - id(TESTDATA_DIR "/builddependencycollector/project/header2.h"), - id(TESTDATA_DIR "/builddependencycollector/external/external1.h"), - id(TESTDATA_DIR "/builddependencycollector/external/external2.h"), - id(TESTDATA_DIR "/builddependencycollector/project/main2.cpp"))))))); + id(TESTDATA_DIR "/builddependencycollector/system/system1.h"), + id(TESTDATA_DIR "/builddependencycollector/system/system2.h"))))))); creator.doInMainThreadAfterFinished(); } @@ -282,15 +335,40 @@ TEST_F(PchCreatorVerySlowTest, ProjectPartPchCleared) ASSERT_FALSE(creator.projectPartPch().isValid()); } -TEST_F(PchCreatorVerySlowTest, SourcesCleared) +TEST_F(PchCreatorVerySlowTest, WatchedSystemIncludesCleared) +{ + creator.generatePch(std::move(pchTask1)); + + creator.clear(); + + ASSERT_THAT(creator.watchedSystemIncludes(), IsEmpty()); +} + +TEST_F(PchCreatorVerySlowTest, WatchedProjectIncludesCleared) +{ + creator.generatePch(std::move(pchTask1)); + + creator.clear(); + + ASSERT_THAT(creator.watchedProjectIncludes(), IsEmpty()); +} + +TEST_F(PchCreatorVerySlowTest, WatchedUserIncludesCleared) { creator.generatePch(std::move(pchTask1)); creator.clear(); - ASSERT_THAT(creator.sources(), IsEmpty()); + ASSERT_THAT(creator.watchedUserIncludes(), IsEmpty()); } +TEST_F(PchCreatorVerySlowTest, WatchedSourcesCleared) +{ + creator.generatePch(std::move(pchTask1)); + creator.clear(); + + ASSERT_THAT(creator.watchedSources(), IsEmpty()); +} TEST_F(PchCreatorVerySlowTest, ClangToolCleared) { creator.generatePch(std::move(pchTask1)); @@ -306,6 +384,9 @@ TEST_F(PchCreatorVerySlowTest, FaultyProjectPartPchForCreatesFaultyPchForPchTask 0, {id(TESTDATA_DIR "/builddependencycollector/project/faulty.cpp")}, {}, + {}, + {}, + {}, {{"DEFINE", "1", 1}}, {}, {}, @@ -336,20 +417,37 @@ TEST_F(PchCreatorSlowTest, NoIncludesInTheMainThreadCalls) { pchTask1.includes = {}; creator.generatePch(std::move(pchTask1)); - EXPECT_CALL(mockPchManagerClient, precompiledHeadersUpdated( Field(&ClangBackEnd::PrecompiledHeadersUpdatedMessage::projectPartIds, ElementsAre(Eq(creator.projectPartPch().projectPartId))))); EXPECT_CALL(mockClangPathWatcher, + updateIdPaths(ElementsAre( + AllOf(Field(&ClangBackEnd::IdPaths::id, ProjectChunkId{1, SourceType::Source}), + Field(&ClangBackEnd::IdPaths::filePathIds, + UnorderedElementsAre(id(main2Path))))))); + EXPECT_CALL(mockClangPathWatcher, + updateIdPaths(ElementsAre(AllOf( + Field(&ClangBackEnd::IdPaths::id, ProjectChunkId{1, SourceType::UserInclude}), + Field(&ClangBackEnd::IdPaths::filePathIds, + UnorderedElementsAre( + id(TESTDATA_DIR "/builddependencycollector/project/header1.h"), + id(TESTDATA_DIR "/builddependencycollector/project/header2.h"))))))); + EXPECT_CALL( + mockClangPathWatcher, + updateIdPaths(ElementsAre( + AllOf(Field(&ClangBackEnd::IdPaths::id, ProjectChunkId{1, SourceType::ProjectInclude}), + Field(&ClangBackEnd::IdPaths::filePathIds, + UnorderedElementsAre( + id(TESTDATA_DIR "/builddependencycollector/external/external1.h"), + id(TESTDATA_DIR "/builddependencycollector/external/external2.h"))))))); + EXPECT_CALL(mockClangPathWatcher, updateIdPaths(ElementsAre(AllOf( - Field(&ClangBackEnd::IdPaths::id, 1), + Field(&ClangBackEnd::IdPaths::id, ProjectChunkId{1, SourceType::SystemInclude}), Field(&ClangBackEnd::IdPaths::filePathIds, UnorderedElementsAre( - id(TESTDATA_DIR "/builddependencycollector/project/header2.h"), - id(TESTDATA_DIR "/builddependencycollector/external/external1.h"), - id(TESTDATA_DIR "/builddependencycollector/external/external2.h"), - id(TESTDATA_DIR "/builddependencycollector/project/main2.cpp"))))))); + id(TESTDATA_DIR "/builddependencycollector/system/system1.h"), + id(TESTDATA_DIR "/builddependencycollector/system/system2.h"))))))); EXPECT_CALL(mockBuildDependenciesStorage, updatePchCreationTimeStamp(Gt(0), Eq(1))); creator.doInMainThreadAfterFinished(); diff --git a/tests/unit/unittest/pchmanagerserver-test.cpp b/tests/unit/unittest/pchmanagerserver-test.cpp index 47b7d987ab..4657051fc5 100644 --- a/tests/unit/unittest/pchmanagerserver-test.cpp +++ b/tests/unit/unittest/pchmanagerserver-test.cpp @@ -25,11 +25,12 @@ #include "googletest.h" +#include "mockbuilddependenciesstorage.h" #include "mockclangpathwatcher.h" +#include "mockgeneratedfiles.h" #include "mockpchmanagerclient.h" #include "mockpchtaskgenerator.h" #include "mockprojectpartsmanager.h" -#include "mockgeneratedfiles.h" #include <filepathcaching.h> #include <pchmanagerserver.h> @@ -42,12 +43,13 @@ #include <updateprojectpartsmessage.h> namespace { -using Utils::PathString; -using Utils::SmallString; -using ClangBackEnd::V2::FileContainer; -using ClangBackEnd::V2::FileContainers; +using ClangBackEnd::FilePathId; using ClangBackEnd::ProjectPartContainer; using ClangBackEnd::ProjectPartContainers; +using ClangBackEnd::V2::FileContainer; +using ClangBackEnd::V2::FileContainers; +using Utils::PathString; +using Utils::SmallString; using UpToDataProjectParts = ClangBackEnd::ProjectPartsManagerInterface::UpToDataProjectParts; class PchManagerServer : public ::testing::Test @@ -71,21 +73,27 @@ protected: NiceMock<MockClangPathWatcher> mockClangPathWatcher; NiceMock<MockProjectPartsManager> mockProjectPartsManager; NiceMock<MockGeneratedFiles> mockGeneratedFiles; + NiceMock<MockBuildDependenciesStorage> mockBuildDependenciesStorage; Sqlite::Database database{":memory:", Sqlite::JournalMode::Memory}; ClangBackEnd::RefactoringDatabaseInitializer<Sqlite::Database> initializer{database}; ClangBackEnd::FilePathCaching filePathCache{database}; ClangBackEnd::PchManagerServer server{mockClangPathWatcher, mockPchTaskGenerator, mockProjectPartsManager, - mockGeneratedFiles}; + mockGeneratedFiles, + mockBuildDependenciesStorage}; NiceMock<MockPchManagerClient> mockPchManagerClient; ClangBackEnd::ProjectPartId projectPartId1{1}; ClangBackEnd::ProjectPartId projectPartId2{2}; + ClangBackEnd::ProjectPartId projectPartId3{3}; + ClangBackEnd::ProjectPartId projectPartId4{4}; + ClangBackEnd::ProjectPartId projectPartId5{5}; + ClangBackEnd::ProjectPartId projectPartId6{6}; PathString main1Path = TESTDATA_DIR "/BuildDependencyCollector_main3.cpp"; PathString main2Path = TESTDATA_DIR "/BuildDependencyCollector_main2.cpp"; PathString header1Path = TESTDATA_DIR "/BuildDependencyCollector_header1.h"; PathString header2Path = TESTDATA_DIR "/BuildDependencyCollector_header2.h"; - ClangBackEnd::IdPaths idPath{projectPartId1, {1, 2}}; + ClangBackEnd::IdPaths idPath{{projectPartId1, ClangBackEnd::SourceType::Source}, {1, 2}}; ProjectPartContainer projectPart1{ projectPartId1, {"-I", TESTDATA_DIR, "-Wno-pragma-once-outside-header"}, @@ -108,6 +116,50 @@ protected: Utils::Language::C, Utils::LanguageVersion::C11, Utils::LanguageExtension::All}; + ProjectPartContainer projectPart3{ + projectPartId3, + {"-I", TESTDATA_DIR, "-Wno-pragma-once-outside-header"}, + {{"DEFINE", "1", 1}}, + {{"/includes", 1, ClangBackEnd::IncludeSearchPathType::BuiltIn}}, + {{"/project/includes", 1, ClangBackEnd::IncludeSearchPathType::User}}, + {id(header1Path)}, + {id(main1Path)}, + Utils::Language::C, + Utils::LanguageVersion::C11, + Utils::LanguageExtension::All}; + ProjectPartContainer projectPart4{ + projectPartId4, + {"-x", "c++-header", "-Wno-pragma-once-outside-header"}, + {{"DEFINE", "1", 1}}, + {{"/includes", 1, ClangBackEnd::IncludeSearchPathType::BuiltIn}}, + {{"/project/includes", 1, ClangBackEnd::IncludeSearchPathType::User}}, + {id(header2Path)}, + {id(main2Path)}, + Utils::Language::C, + Utils::LanguageVersion::C11, + Utils::LanguageExtension::All}; + ProjectPartContainer projectPart5{ + projectPartId5, + {"-I", TESTDATA_DIR, "-Wno-pragma-once-outside-header"}, + {{"DEFINE", "1", 1}}, + {{"/includes", 1, ClangBackEnd::IncludeSearchPathType::BuiltIn}}, + {{"/project/includes", 1, ClangBackEnd::IncludeSearchPathType::User}}, + {id(header1Path)}, + {id(main1Path)}, + Utils::Language::C, + Utils::LanguageVersion::C11, + Utils::LanguageExtension::All}; + ProjectPartContainer projectPart6{ + projectPartId6, + {"-x", "c++-header", "-Wno-pragma-once-outside-header"}, + {{"DEFINE", "1", 1}}, + {{"/includes", 1, ClangBackEnd::IncludeSearchPathType::BuiltIn}}, + {{"/project/includes", 1, ClangBackEnd::IncludeSearchPathType::User}}, + {id(header2Path)}, + {id(main2Path)}, + Utils::Language::C, + Utils::LanguageVersion::C11, + Utils::LanguageExtension::All}; std::vector<ProjectPartContainer> projectParts{projectPart1, projectPart2}; std::vector<ProjectPartContainer> projectParts1{projectPart1}; std::vector<ProjectPartContainer> projectParts2{projectPart2}; @@ -169,19 +221,78 @@ TEST_F(PchManagerServer, SetPathWatcherNotifier) ClangBackEnd::PchManagerServer server{mockClangPathWatcher, mockPchTaskGenerator, mockProjectPartsManager, - mockGeneratedFiles}; + mockGeneratedFiles, + mockBuildDependenciesStorage}; } TEST_F(PchManagerServer, UpdateProjectPartQueueByPathIds) { - server.updateProjectParts( - ClangBackEnd::UpdateProjectPartsMessage{{projectPart1}, {"toolChainArgument"}}); + InSequence s; + server.updateProjectParts(ClangBackEnd::UpdateProjectPartsMessage{ + {projectPart1, projectPart2, projectPart3, projectPart4, projectPart5, projectPart6}, + {"toolChainArgument"}}); + + EXPECT_CALL(mockProjectPartsManager, + projects(ElementsAre(projectPart1.projectPartId, projectPart2.projectPartId))) + .WillOnce( + Return(std::vector<ClangBackEnd::ProjectPartContainer>{{projectPart1, projectPart2}})); + EXPECT_CALL(mockPchTaskGenerator, + addProjectParts(ElementsAre(projectPart1, projectPart2), + ElementsAre("toolChainArgument"))); + EXPECT_CALL(mockProjectPartsManager, + projects(ElementsAre(projectPart4.projectPartId, projectPart5.projectPartId))) + .WillOnce( + Return(std::vector<ClangBackEnd::ProjectPartContainer>{{projectPart4, projectPart5}})); + EXPECT_CALL(mockPchTaskGenerator, + addNonSystemProjectParts(ElementsAre(projectPart4, projectPart5), + ElementsAre("toolChainArgument"))); + + server.pathsWithIdsChanged({{{projectPartId1, ClangBackEnd::SourceType::TopSystemInclude}, {}}, + {{projectPartId1, ClangBackEnd::SourceType::ProjectInclude}, {}}, + {{projectPartId1, ClangBackEnd::SourceType::UserInclude}, {}}, + {{projectPartId2, ClangBackEnd::SourceType::SystemInclude}, {}}, + {{projectPartId2, ClangBackEnd::SourceType::ProjectInclude}, {}}, + {{projectPartId3, ClangBackEnd::SourceType::UserInclude}, {}}, + {{projectPartId4, ClangBackEnd::SourceType::TopProjectInclude}, {}}, + {{projectPartId4, ClangBackEnd::SourceType::Source}, {}}, + {{projectPartId4, ClangBackEnd::SourceType::UserInclude}, {}}, + {{projectPartId5, ClangBackEnd::SourceType::ProjectInclude}, {}}, + {{projectPartId6, ClangBackEnd::SourceType::Source}, {}}}); +} + +TEST_F(PchManagerServer, DontUpdateProjectPartQueueByPathIdsIfItUserFile) +{ + server.updateProjectParts(ClangBackEnd::UpdateProjectPartsMessage{{projectPart1, projectPart2}, + {"toolChainArgument"}}); + + EXPECT_CALL(mockProjectPartsManager, projects(_)).Times(0); + EXPECT_CALL(mockPchTaskGenerator, addProjectParts(_, _)).Times(0); - EXPECT_CALL(mockProjectPartsManager, projects(ElementsAre(projectPart1.projectPartId))) - .WillOnce(Return(std::vector<ClangBackEnd::ProjectPartContainer>{{projectPart1}})); - EXPECT_CALL(mockPchTaskGenerator, addProjectParts(ElementsAre(projectPart1), ElementsAre("toolChainArgument"))); + server.pathsWithIdsChanged({{{projectPartId1, ClangBackEnd::SourceType::UserInclude}, {}}, + {{projectPartId2, ClangBackEnd::SourceType::Source}, {}}}); +} + +TEST_F(PchManagerServer, ShortcutPrecompiledHeaderGenerationForUserIncludesAndSources) +{ + EXPECT_CALL(mockPchManagerClient, + precompiledHeadersUpdated( + Field(&ClangBackEnd::PrecompiledHeadersUpdatedMessage::projectPartIds, + UnorderedElementsAre(projectPartId3, projectPartId6)))); + + server.pathsWithIdsChanged({{{projectPartId1, ClangBackEnd::SourceType::TopProjectInclude}, {}}, + {{projectPartId2, ClangBackEnd::SourceType::TopSystemInclude}, {}}, + {{projectPartId3, ClangBackEnd::SourceType::UserInclude}, {}}, + {{projectPartId4, ClangBackEnd::SourceType::ProjectInclude}, {}}, + {{projectPartId5, ClangBackEnd::SourceType::SystemInclude}, {}}, + {{projectPartId6, ClangBackEnd::SourceType::Source}, {}}}); +} +TEST_F(PchManagerServer, ResetTimeStampForChangedFilesInDatabase) +{ + EXPECT_CALL(mockBuildDependenciesStorage, + insertOrUpdateIndexingTimeStamps(ElementsAre(FilePathId{1}, FilePathId{3}, FilePathId{5}), + TypedEq<ClangBackEnd::TimeStamp>(0))); - server.pathsWithIdsChanged({projectPartId1}); + server.pathsChanged({1, 3, 5}); } TEST_F(PchManagerServer, SetPchCreationProgress) @@ -214,7 +325,7 @@ TEST_F(PchManagerServer, RemoveToolChainsArguments) EXPECT_CALL(mockPchTaskGenerator, addProjectParts(_, _)).Times(0); server.removeProjectParts(removeProjectPartsMessage.clone()); - server.pathsWithIdsChanged({projectPart1.projectPartId}); + server.pathsWithIdsChanged({{{projectPart1.projectPartId, ClangBackEnd::SourceType::Source}, {}}}); } TEST_F(PchManagerServer, DontGeneratePchIfGeneratedFilesAreNotValid) diff --git a/tests/unit/unittest/pchtaskgenerator-test.cpp b/tests/unit/unittest/pchtaskgenerator-test.cpp index cb9df32235..9dd2e09273 100644 --- a/tests/unit/unittest/pchtaskgenerator-test.cpp +++ b/tests/unit/unittest/pchtaskgenerator-test.cpp @@ -26,6 +26,7 @@ #include "googletest.h" #include "mockbuilddependenciesprovider.h" +#include "mockpchtaskqueue.h" #include "mockpchtasksmerger.h" #include <pchtaskgenerator.h> @@ -52,11 +53,13 @@ class PchTaskGenerator : public testing::Test protected: NiceMock<MockBuildDependenciesProvider> mockBuildDependenciesProvider; NiceMock<MockPchTasksMerger> mockPchTaskMerger; + NiceMock<MockPchTaskQueue> mockPchTaskQueue; NiceMock<MockFunction<void(int, int)>> mockProgressCounterCallback; ClangBackEnd::ProgressCounter progressCounter{mockProgressCounterCallback.AsStdFunction()}; ClangBackEnd::PchTaskGenerator generator{mockBuildDependenciesProvider, mockPchTaskMerger, - progressCounter}; + progressCounter, + mockPchTaskQueue}; ClangBackEnd::ProjectPartContainer projectPart1{ 1, {"--yi"}, @@ -84,7 +87,8 @@ protected: {2, SourceType::UserInclude, 1}, {3, SourceType::TopProjectInclude, 1}, {4, SourceType::SystemInclude, 1}, - {5, SourceType::TopSystemInclude, 1}}; + {5, SourceType::TopSystemInclude, 1}, + {6, SourceType::Source, 1}}; UsedMacros usedMacros{{"LIANG", 0},{"YI", 1}, {"ER", 2}, {"SAN", 3}, {"SE", 4}, {"WU", 5}}; BuildDependency buildDependency{firstSources, usedMacros, {}, {}, {}}; }; @@ -100,7 +104,10 @@ TEST_F(PchTaskGenerator, AddProjectParts) Field(&PchTaskSet::system, AllOf(Field(&PchTask::projectPartIds, ElementsAre(ProjectPartId{1})), Field(&PchTask::includes, ElementsAre(5)), - Field(&PchTask::sources, IsEmpty()), + Field(&PchTask::watchedSystemIncludes, IsEmpty()), + Field(&PchTask::watchedProjectIncludes, IsEmpty()), + Field(&PchTask::watchedUserIncludes, IsEmpty()), + Field(&PchTask::watchedUserSources, IsEmpty()), Field(&PchTask::compilerMacros, ElementsAre(CompilerMacro{"SE", "4", 4}, CompilerMacro{"WU", "5", 5})), Field(&PchTask::systemIncludeSearchPaths, @@ -117,7 +124,10 @@ TEST_F(PchTaskGenerator, AddProjectParts) &PchTaskSet::project, AllOf(Field(&PchTask::projectPartIds, ElementsAre(ProjectPartId{1})), Field(&PchTask::includes, ElementsAre(3)), - Field(&PchTask::sources, ElementsAre(1, 3, 4, 5)), + Field(&PchTask::watchedSystemIncludes, ElementsAre(4, 5)), + Field(&PchTask::watchedProjectIncludes, ElementsAre(1, 3)), + Field(&PchTask::watchedUserIncludes, ElementsAre(2)), + Field(&PchTask::watchedUserSources, ElementsAre(6)), Field(&PchTask::compilerMacros, ElementsAre(CompilerMacro{"YI", "1", 1}, CompilerMacro{"SAN", "3", 3})), Field(&PchTask::systemIncludeSearchPaths, @@ -138,6 +148,36 @@ TEST_F(PchTaskGenerator, AddProjectParts) generator.addProjectParts({projectPart1}, {"ToolChainArgument"}); } +TEST_F(PchTaskGenerator, AddNonSystemProjectParts) +{ + ON_CALL(mockBuildDependenciesProvider, create(_)).WillByDefault(Return(buildDependency)); + + EXPECT_CALL( + mockPchTaskQueue, + addProjectPchTasks(ElementsAre(AllOf( + Field(&PchTask::projectPartIds, ElementsAre(ProjectPartId{1})), + Field(&PchTask::includes, ElementsAre(3)), + Field(&PchTask::watchedSystemIncludes, ElementsAre(4, 5)), + Field(&PchTask::watchedProjectIncludes, ElementsAre(1, 3)), + Field(&PchTask::watchedUserIncludes, ElementsAre(2)), + Field(&PchTask::watchedUserSources, ElementsAre(6)), + Field(&PchTask::compilerMacros, + ElementsAre(CompilerMacro{"YI", "1", 1}, CompilerMacro{"SAN", "3", 3})), + Field(&PchTask::systemIncludeSearchPaths, + ElementsAre(IncludeSearchPath{"/system/path", 2, IncludeSearchPathType::System}, + IncludeSearchPath{"/builtin/path", 3, IncludeSearchPathType::BuiltIn}, + IncludeSearchPath{"/framework/path", 1, IncludeSearchPathType::System})), + Field(&PchTask::projectIncludeSearchPaths, + ElementsAre(IncludeSearchPath{"/to/path1", 1, IncludeSearchPathType::User}, + IncludeSearchPath{"/to/path2", 2, IncludeSearchPathType::User})), + Field(&PchTask::toolChainArguments, ElementsAre("--yi")), + Field(&PchTask::language, Eq(Utils::Language::Cxx)), + Field(&PchTask::languageVersion, Eq(Utils::LanguageVersion::CXX11)), + Field(&PchTask::languageExtension, Eq(Utils::LanguageExtension::All)))))); + + generator.addNonSystemProjectParts({projectPart1}, {"ToolChainArgument"}); +} + TEST_F(PchTaskGenerator, ProgressCounter) { ON_CALL(mockBuildDependenciesProvider, create(_)).WillByDefault(Return(buildDependency)); diff --git a/tests/unit/unittest/pchtaskqueue-test.cpp b/tests/unit/unittest/pchtaskqueue-test.cpp index 1754cea562..0715602f97 100644 --- a/tests/unit/unittest/pchtaskqueue-test.cpp +++ b/tests/unit/unittest/pchtaskqueue-test.cpp @@ -67,6 +67,9 @@ protected: PchTask systemTask1{1, {1, 2}, {1, 2}, + {2, 3}, + {3, 4}, + {6, 7}, {{"YI", "1", 1}, {"SAN", "3", 3}}, {{"LIANG", 0}, {"YI", 1}}, {"--yi"}, @@ -75,6 +78,9 @@ protected: PchTask systemTask2{2, {1, 2}, {1, 2}, + {2, 3}, + {3, 4}, + {6, 7}, {{"YI", "1", 1}, {"SAN", "3", 3}}, {{"LIANG", 0}, {"YI", 1}}, {"--yi"}, @@ -83,6 +89,9 @@ protected: PchTask systemTask2b{2, {3, 4}, {3, 4}, + {5, 6}, + {4, 7}, + {8, 9}, {{"YI", "1", 1}, {"SAN", "3", 3}}, {{"LIANG", 0}, {"YI", 1}}, {"--yi"}, @@ -91,6 +100,9 @@ protected: PchTask systemTask3{3, {1, 2}, {1, 2}, + {2, 3}, + {3, 4}, + {6, 7}, {{"YI", "1", 1}, {"SAN", "3", 3}}, {{"LIANG", 0}, {"YI", 1}}, {"--yi"}, @@ -99,6 +111,9 @@ protected: PchTask projectTask1{1, {11, 12}, {11, 12}, + {12, 13}, + {13, 14}, + {16, 17}, {{"SE", "4", 4}, {"WU", "5", 5}}, {{"ER", 2}, {"SAN", 3}}, {"--yi"}, @@ -107,6 +122,9 @@ protected: PchTask projectTask2{2, {11, 12}, {11, 12}, + {12, 13}, + {13, 14}, + {16, 17}, {{"SE", "4", 4}, {"WU", "5", 5}}, {{"ER", 2}, {"SAN", 3}}, {"--yi"}, @@ -115,6 +133,9 @@ protected: PchTask projectTask2b{2, {21, 22}, {11, 12}, + {22, 23}, + {23, 24}, + {26, 27}, {{"SE", "4", 4}, {"WU", "5", 5}}, {{"ER", 2}, {"SAN", 3}}, {"--yi"}, @@ -123,6 +144,9 @@ protected: PchTask projectTask3{3, {21, 22}, {21, 22}, + {22, 23}, + {23, 24}, + {26, 27}, {{"SE", "4", 4}, {"WU", "5", 5}}, {{"ER", 2}, {"SAN", 3}}, {"--yi"}, @@ -131,6 +155,9 @@ protected: PchTask systemTask4{{1, 3}, {1, 2}, {1, 2}, + {2, 3}, + {3, 4}, + {5, 8}, {{"YI", "1", 1}, {"SAN", "3", 3}}, {{"LIANG", 0}, {"YI", 1}}, {"--yi"}, diff --git a/tests/unit/unittest/pchtasksmerger-test.cpp b/tests/unit/unittest/pchtasksmerger-test.cpp index 076e1415b2..28f9593ad4 100644 --- a/tests/unit/unittest/pchtasksmerger-test.cpp +++ b/tests/unit/unittest/pchtasksmerger-test.cpp @@ -54,7 +54,10 @@ protected: ClangBackEnd::PchTasksMerger merger{mockPchTaskQueue}; PchTask systemTask1{1, {1, 2}, - {1, 2, 3}, + {}, + {}, + {}, + {}, {{"YI", "1", 1}, {"SAN", "3", 3}}, {"YI", "LIANG"}, {"--yi"}, @@ -66,6 +69,9 @@ protected: PchTask projectTask1{1, {11, 12}, {11, 12}, + {21, 22}, + {31, 32}, + {41, 42}, {{"SE", "4", 4}, {"WU", "5", 5}}, {"ER", "SAN"}, {"--yi"}, @@ -75,7 +81,10 @@ protected: {"/to/path2", 2, IncludeSearchPathType::User}}}; PchTask systemTask2{2, {11, 12}, - {11, 12, 13}, + {}, + {}, + {}, + {}, {{"SE", "4", 4}, {"WU", "5", 5}}, {"ER", "SAN"}, {"--yi"}, @@ -87,6 +96,9 @@ protected: PchTask projectTask2{2, {11, 12}, {11, 12}, + {21, 22}, + {31, 32}, + {41, 42}, {{"SE", "4", 4}, {"WU", "5", 5}}, {"ER", "SAN"}, {"--yi"}, @@ -97,7 +109,10 @@ protected: {"/to/path2", 2, IncludeSearchPathType::User}}}; PchTask systemTask3{3, {1, 2}, - {1, 2}, + {}, + {}, + {}, + {}, {{"YI", "2", 1}, {"SAN", "3", 3}}, {"YI", "LIANG"}, {"--yi"}, @@ -268,18 +283,25 @@ TEST_F(PchTasksMerger, DontMergeIncludes) ASSERT_THAT(systemTask1.includes, ElementsAre(1, 2)); } -TEST_F(PchTasksMerger, MergeAllIncludes) +TEST_F(PchTasksMerger, DontMergeWatchedSystemSources) { Merger::mergePchTasks(systemTask1, systemTask2); - ASSERT_THAT(systemTask1.sources, ElementsAre(1, 2, 3, 11, 12, 13)); + ASSERT_THAT(systemTask1.watchedSystemIncludes, IsEmpty()); +} + +TEST_F(PchTasksMerger, DontMergeWatchedProjectSources) +{ + Merger::mergePchTasks(systemTask1, systemTask3); + + ASSERT_THAT(systemTask1.watchedProjectIncludes, IsEmpty()); } -TEST_F(PchTasksMerger, DontAllMergeIncludes) +TEST_F(PchTasksMerger, DontMergeWatchedUserSources) { Merger::mergePchTasks(systemTask1, systemTask3); - ASSERT_THAT(systemTask1.sources, ElementsAre(1, 2, 3)); + ASSERT_THAT(systemTask1.watchedUserSources, IsEmpty()); } TEST_F(PchTasksMerger, MergeProjectIds) diff --git a/tests/unit/unittest/projectpartsstorage-test.cpp b/tests/unit/unittest/projectpartsstorage-test.cpp index 3c13f33ad6..ba1b6f7063 100644 --- a/tests/unit/unittest/projectpartsstorage-test.cpp +++ b/tests/unit/unittest/projectpartsstorage-test.cpp @@ -463,7 +463,6 @@ protected: Sqlite::Database database{":memory:", Sqlite::JournalMode::Memory}; ClangBackEnd::RefactoringDatabaseInitializer<Sqlite::Database> databaseInitializer{database}; Storage storage{database}; - ClangBackEnd::SymbolStorage<> symbolStorage{database}; ClangBackEnd::BuildDependenciesStorage<> buildDependenciesStorage{database}; }; @@ -505,13 +504,13 @@ TEST_F(ProjectPartsStorageSlow, FetchProjectParts) TEST_F(ProjectPartsStorageSlow, ResetDependentIndexingTimeStamps) { - symbolStorage.insertOrUpdateIndexingTimeStamps({1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, 34); + buildDependenciesStorage.insertOrUpdateIndexingTimeStamps({1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, 34); buildDependenciesStorage.insertOrUpdateSourceDependencies( {{3, 1}, {4, 1}, {1, 2}, {7, 5}, {8, 6}, {6, 5}, {9, 10}}); storage.resetIndexingTimeStamps({projectPart1, projectPart2}); - ASSERT_THAT(symbolStorage.fetchIndexingTimeStamps(), + ASSERT_THAT(buildDependenciesStorage.fetchIndexingTimeStamps(), ElementsAre(SourceTimeStamp{1, 0}, SourceTimeStamp{2, 0}, SourceTimeStamp{3, 0}, diff --git a/tests/unit/unittest/refactoringclient-test.cpp b/tests/unit/unittest/refactoringclient-test.cpp index 00a390dd14..81036feba0 100644 --- a/tests/unit/unittest/refactoringclient-test.cpp +++ b/tests/unit/unittest/refactoringclient-test.cpp @@ -107,46 +107,11 @@ protected: ProjectExplorer::Project project; CppTools::ProjectPart::Ptr projectPart; CppTools::ProjectFile projectFile{qStringFilePath, CppTools::ProjectFile::CXXSource}; - SourceLocationsForRenamingMessage renameMessage{"symbol", - {{{42, 1, 1, 0}, {42, 2, 5, 10}}}, - 1}; SourceRangesForQueryMessage queryResultMessage{{{{42, 1, 1, 0, 1, 5, 4, ""}, {42, 2, 1, 5, 2, 5, 10, ""}}}}; SourceRangesForQueryMessage emptyQueryResultMessage; }; -TEST_F(RefactoringClient, SourceLocationsForRenaming) -{ - client.setLocalRenamingCallback(mockLocalRenaming.AsStdFunction()); - - EXPECT_CALL(mockLocalRenaming, Call(renameMessage.symbolName.toQString(), - renameMessage.sourceLocations, - renameMessage.textDocumentRevision)); - - client.sourceLocationsForRenamingMessage(std::move(renameMessage)); -} - -TEST_F(RefactoringClient, AfterSourceLocationsForRenamingEngineIsUsableAgain) -{ - client.setLocalRenamingCallback(mockLocalRenaming.AsStdFunction()); - EXPECT_CALL(mockLocalRenaming, Call(_,_,_)); - - client.sourceLocationsForRenamingMessage(std::move(renameMessage)); - - ASSERT_TRUE(engine.isRefactoringEngineAvailable()); -} - -TEST_F(RefactoringClient, AfterStartLocalRenameHasValidCallback) -{ - engine.startLocalRenaming(CppTools::CursorInEditor{cursor, filePath}, - projectPart.data(), - [&] (const QString &, - const ClangBackEnd::SourceLocationsContainer &, - int) {}); - - ASSERT_TRUE(client.hasValidLocalRenamingCallback()); -} - TEST_F(RefactoringClient, CallAddResultsForEmptyQueryMessage) { EXPECT_CALL(mockSearchHandle, addResult(_ ,_ ,_)) diff --git a/tests/unit/unittest/refactoringclientserverinprocess-test.cpp b/tests/unit/unittest/refactoringclientserverinprocess-test.cpp index 113e21859e..8b6237bfad 100644 --- a/tests/unit/unittest/refactoringclientserverinprocess-test.cpp +++ b/tests/unit/unittest/refactoringclientserverinprocess-test.cpp @@ -90,28 +90,6 @@ TEST_F(RefactoringClientServerInProcess, SendAliveMessage) scheduleClientMessages(); } -TEST_F(RefactoringClientServerInProcess, SendSourceLocationsForRenamingMessage) -{ - ClangBackEnd::SourceLocationsContainer container; - ClangBackEnd::SourceLocationsForRenamingMessage message("symbolName", std::move(container), 1); - - EXPECT_CALL(mockRefactoringClient, sourceLocationsForRenamingMessage(message)); - - clientProxy.sourceLocationsForRenamingMessage(message.clone()); - scheduleClientMessages(); -} - -TEST_F(RefactoringClientServerInProcess, SendRequestSourceLocationsForRenamingMessage) -{ - RequestSourceLocationsForRenamingMessage message{ - {TESTDATA_DIR, "renamevariable.cpp"}, 1, 5, "int v;\n\nint x = v + 3;\n", {"cc"}, 1}; - - EXPECT_CALL(mockRefactoringServer, requestSourceLocationsForRenamingMessage(message)); - - serverProxy.requestSourceLocationsForRenamingMessage(message.clone()); - scheduleServerMessages(); -} - TEST_F(RefactoringClientServerInProcess, SourceRangesAndDiagnosticsForQueryMessage) { ClangBackEnd::SourceRangesContainer sourceRangesContainer; diff --git a/tests/unit/unittest/refactoringengine-test.cpp b/tests/unit/unittest/refactoringengine-test.cpp index 3cf5961dd1..280a240942 100644 --- a/tests/unit/unittest/refactoringengine-test.cpp +++ b/tests/unit/unittest/refactoringengine-test.cpp @@ -49,8 +49,6 @@ using testing::_; using CppTools::CompilerOptionsBuilder; -using ClangBackEnd::RequestSourceLocationsForRenamingMessage; - using Utils::SmallString; using Utils::SmallStringVector; @@ -90,33 +88,6 @@ protected: CppTools::ProjectFile projectFile{qStringFilePath, CppTools::ProjectFile::CXXSource}; }; -TEST_F(RefactoringEngine, SendRequestSourceLocationsForRenamingMessage) -{ - cursor.setPosition(11); - RequestSourceLocationsForRenamingMessage message(clangBackEndFilePath.clone(), - 2, - 5, - fileContent, - commandLine.clone(), - 1); - - EXPECT_CALL(mockRefactoringServer, requestSourceLocationsForRenamingMessage(message)) - .Times(1); - - engine.startLocalRenaming(CppTools::CursorInEditor{cursor, filePath}, - projectPart.data(), {}); -} - -TEST_F(RefactoringEngine, AfterSendRequestSourceLocationsForRenamingMessageIsUnusable) -{ - EXPECT_CALL(mockRefactoringServer, requestSourceLocationsForRenamingMessage(_)); - - engine.startLocalRenaming(CppTools::CursorInEditor{cursor, filePath}, - projectPart.data(), {}); - - ASSERT_FALSE(engine.isRefactoringEngineAvailable()); -} - TEST_F(RefactoringEngine, ExpectSourceUsagesAtInFindUsages) { cursor.setPosition(11); diff --git a/tests/unit/unittest/refactoringserver-test.cpp b/tests/unit/unittest/refactoringserver-test.cpp index 8a81e37258..74363de35f 100644 --- a/tests/unit/unittest/refactoringserver-test.cpp +++ b/tests/unit/unittest/refactoringserver-test.cpp @@ -56,11 +56,9 @@ using testing::_; using ClangBackEnd::FilePath; using ClangBackEnd::IncludeSearchPaths; using ClangBackEnd::IncludeSearchPathType; -using ClangBackEnd::RequestSourceLocationsForRenamingMessage; using ClangBackEnd::RequestSourceRangesAndDiagnosticsForQueryMessage; using ClangBackEnd::RequestSourceRangesForQueryMessage; using ClangBackEnd::SourceLocationsContainer; -using ClangBackEnd::SourceLocationsForRenamingMessage; using ClangBackEnd::SourceRangesAndDiagnosticsForQueryMessage; using ClangBackEnd::SourceRangesContainer; using ClangBackEnd::SourceRangesForQueryMessage; @@ -109,23 +107,6 @@ protected: using RefactoringServerSlowTest = RefactoringServer; using RefactoringServerVerySlowTest = RefactoringServer; -TEST_F(RefactoringServerSlowTest, RequestSourceLocationsForRenamingMessage) -{ - RequestSourceLocationsForRenamingMessage message{ - {TESTDATA_DIR, "renamevariable.cpp"}, 1, 5, "int v;\n\nint x = v + 3;\n", {"cc"}, 1}; - - EXPECT_CALL(mockRefactoringClient, - sourceLocationsForRenamingMessage( - AllOf(Field(&SourceLocationsForRenamingMessage::textDocumentRevision, 1), - Field(&SourceLocationsForRenamingMessage::symbolName, "v"), - Field(&SourceLocationsForRenamingMessage::sourceLocations, - Property(&SourceLocationsContainer::sourceLocationContainers, - AllOf(Contains(IsSourceLocation(1, 5)), - Contains(IsSourceLocation(3, 9)))))))); - - refactoringServer.requestSourceLocationsForRenamingMessage(std::move(message)); -} - TEST_F(RefactoringServerSlowTest, RequestSingleSourceRangesForQueryMessage) { RequestSourceRangesForQueryMessage message{"functionDecl()", diff --git a/tests/unit/unittest/symbolfinder-test.cpp b/tests/unit/unittest/symbolfinder-test.cpp deleted file mode 100644 index 8f29fe02da..0000000000 --- a/tests/unit/unittest/symbolfinder-test.cpp +++ /dev/null @@ -1,255 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt Creator. -** -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -****************************************************************************/ - -#include "googletest.h" -#include "mockfilepathcaching.h" - -#include <clangrefactoringbackend_global.h> -#include <symbolfinder.h> - -#include "filesystem-utilities.h" - -using ClangBackEnd::FileContent; -using ClangBackEnd::FilePathView; -using ClangBackEnd::NativeFilePath; -using ClangBackEnd::NativeFilePathView; -using ClangBackEnd::SymbolFinder; -namespace { - -inline bool operator==(const ClangBackEnd::NativeFilePath &first, const std::string &second) -{ - return first.path() == second; -} -MATCHER_P2(IsSourceLocation, - line, - column, - std::string(negation ? "isn't" : "is") + "line " + PrintToString(line) + ", column " - + PrintToString(column)) -{ - return arg.line == uint(line) && arg.column == uint(column); -} - -MATCHER_P(StrEq, text, std::string(negation ? "isn't" : "is") + " text " + PrintToString(text)) -{ - return std::string(arg.data(), arg.size()) == std::string(text); -} -using Finder = SymbolFinder; - -class SymbolFinder : public testing::Test -{ -protected: - NiceMock<MockFilePathCaching> filePathCaching; -}; - -using SymbolFinderSlowTest = SymbolFinder; - -TEST_F(SymbolFinder, FileContentFilePath) -{ - FileContent fileContent(NativeFilePath{FilePathView{"/tmp/data.cpp"}}, "int variable;"); - - ASSERT_THAT(fileContent.filePath, toNativePath("/tmp/data.cpp")); -} - -TEST_F(SymbolFinderSlowTest, FindName) -{ - Finder finder(1, 5, filePathCaching); - finder.addFile({TESTDATA_DIR "/renamevariable.cpp"}, "int variable;", {"cc"}); - - finder.findSymbol(); - - ASSERT_THAT(finder.takeSymbolName(), "variable"); -} - -TEST_F(SymbolFinderSlowTest, FindNameInUnsavedFile) -{ - Finder finder(1, 5, filePathCaching); - finder.addFile({TESTDATA_DIR "/renamevariable.cpp"}, "int newVariable;", {"cc"}); - - finder.findSymbol(); - - ASSERT_THAT(finder.takeSymbolName(), "newVariable"); -} - -TEST_F(SymbolFinderSlowTest, FindUsrs) -{ - Finder finder(1, 5, filePathCaching); - finder.addFile({TESTDATA_DIR "/renamevariable.cpp"}, "int variable;", {"cc", "-std=c++14"}); - - finder.findSymbol(); - - ASSERT_THAT(finder.unifiedSymbolResolutions().front(), StrEq("c:@variable")); -} - -TEST_F(SymbolFinderSlowTest, VariableDeclarationSourceLocations) -{ - Finder finder(1, 5, filePathCaching); - finder.addFile({TESTDATA_DIR "/renamevariable.cpp"}, "", {"cc", "-std=c++14"}); - - finder.findSymbol(); - - ASSERT_THAT(finder.sourceLocations().sourceLocationContainers(), - AllOf(Contains(IsSourceLocation(1, 5)), - Contains(IsSourceLocation(3, 9)))); -} - -TEST_F(SymbolFinderSlowTest, VariableUsageSourceLocations) -{ - Finder finder(3, 9, filePathCaching); - finder.addFile({TESTDATA_DIR "/renamevariable.cpp"}, "", {"cc", "-std=c++14"}); - - finder.findSymbol(); - - ASSERT_THAT(finder.sourceLocations().sourceLocationContainers(), - AllOf(Contains(IsSourceLocation(1, 5)), - Contains(IsSourceLocation(3, 9)))); -} - -TEST_F(SymbolFinderSlowTest, TemplateMemberVariableDeclarationSourceLocations) -{ - Finder finder(8, 18, filePathCaching); - finder.addFile({TESTDATA_DIR "/renamevariable.cpp"}, "", {"cc", "-std=c++14"}); - - finder.findSymbol(); - - ASSERT_THAT(finder.sourceLocations().sourceLocationContainers(), - AllOf(Contains(IsSourceLocation(8, 18)), - Contains(IsSourceLocation(15, 14)), - Contains(IsSourceLocation(18, 19)))); -} - -TEST_F(SymbolFinderSlowTest, TemplateMemberVariableUsageSourceLocations) -{ - Finder finder(15, 14, filePathCaching); - finder.addFile({TESTDATA_DIR "/renamevariable.cpp"}, "", {"cc", "-std=c++14"}); - - finder.findSymbol(); - - ASSERT_THAT(finder.sourceLocations().sourceLocationContainers(), - AllOf(Contains(IsSourceLocation(8, 18)), - Contains(IsSourceLocation(15, 14)), - Contains(IsSourceLocation(18, 19)))); -} - -TEST_F(SymbolFinderSlowTest, TemplateMemberVariableUsageInLambdaSourceLocations) -{ - Finder finder(18, 19, filePathCaching); - finder.addFile({TESTDATA_DIR "/renamevariable.cpp"}, "", {"cc", "-std=c++14"}); - - finder.findSymbol(); - - ASSERT_THAT(finder.sourceLocations().sourceLocationContainers(), - AllOf(Contains(IsSourceLocation(8, 18)), - Contains(IsSourceLocation(15, 14)), - Contains(IsSourceLocation(18, 19)))); -} - -TEST_F(SymbolFinderSlowTest, CursorOverMacroDefintionSymbolName) -{ - Finder finder(1, 9, filePathCaching); - finder.addFile({TESTDATA_DIR "/symbolfinder_macro.cpp"}, "", {"cc"}); - - finder.findSymbol(); - - ASSERT_THAT(finder.takeSymbolName(), "Macro"); -} - -TEST_F(SymbolFinderSlowTest, CursorOverMacroExpansionSymbolName) -{ - Finder finder(10, 10, filePathCaching); - finder.addFile({TESTDATA_DIR "/symbolfinder_macro.cpp"}, "", {"cc"}); - - finder.findSymbol(); - - ASSERT_THAT(finder.takeSymbolName(), "Macro"); -} - -TEST_F(SymbolFinderSlowTest, FindMacroDefinition) -{ - Finder finder(1, 9, filePathCaching); - finder.addFile({TESTDATA_DIR "/symbolfinder_macro.cpp"}, "", {"cc"}); - - finder.findSymbol(); - - ASSERT_THAT(finder.sourceLocations().sourceLocationContainers(), - Contains(IsSourceLocation(1, 9))); -} - -TEST_F(SymbolFinderSlowTest, FindMacroExpansion) -{ - Finder finder(1, 9, filePathCaching); - finder.addFile({TESTDATA_DIR "/symbolfinder_macro.cpp"}, "", {"cc"}); - - finder.findSymbol(); - - ASSERT_THAT(finder.sourceLocations().sourceLocationContainers(), - Contains(IsSourceLocation(5, 17))); -} - -TEST_F(SymbolFinderSlowTest, DoNotFindUndedefinedMacroExpansion) -{ - Finder finder(1, 9, filePathCaching); - finder.addFile({TESTDATA_DIR "/symbolfinder_macro.cpp"}, "", {"cc"}); - - finder.findSymbol(); - - ASSERT_THAT(finder.sourceLocations().sourceLocationContainers(), - Not(Contains(IsSourceLocation(10, 10)))); -} - -TEST_F(SymbolFinderSlowTest, FindMacroDefinitionFromMacroExpansion) -{ - Finder finder(10, 10, filePathCaching); - finder.addFile({TESTDATA_DIR "/symbolfinder_macro.cpp"}, "", {"cc"}); - - finder.findSymbol(); - - ASSERT_THAT(finder.sourceLocations().sourceLocationContainers(), - Contains(IsSourceLocation(8, 9))); -} - - -TEST_F(SymbolFinderSlowTest, FindMacroExpansionBeforeMacroExpansionWithCursor) -{ - Finder finder(12, 10, filePathCaching); - finder.addFile({TESTDATA_DIR "/symbolfinder_macro.cpp"}, "", {"cc"}); - - finder.findSymbol(); - - ASSERT_THAT(finder.sourceLocations().sourceLocationContainers(), - Contains(IsSourceLocation(10, 10))); -} - -TEST_F(SymbolFinderSlowTest, FindMacroExpansionAfterMacroExpansionWithCursor) -{ - Finder finder(10, 10, filePathCaching); - finder.addFile({TESTDATA_DIR "/symbolfinder_macro.cpp"}, "", {"cc"}); - - finder.findSymbol(); - - ASSERT_THAT(finder.sourceLocations().sourceLocationContainers(), - Contains(IsSourceLocation(12, 10))); -} - -} // namespace diff --git a/tests/unit/unittest/symbolindexer-test.cpp b/tests/unit/unittest/symbolindexer-test.cpp index 16e0fc81b0..3e0359cd8d 100644 --- a/tests/unit/unittest/symbolindexer-test.cpp +++ b/tests/unit/unittest/symbolindexer-test.cpp @@ -116,11 +116,11 @@ protected: .WillByDefault(Return(artefact)); ON_CALL(mockBuildDependenciesStorage, fetchLowestLastModifiedTime(A<FilePathId>())).WillByDefault(Return(-1)); ON_CALL(mockCollector, collectSymbols()).WillByDefault(Return(true)); - ON_CALL(mockSymbolStorage, fetchDependentSourceIds(sourceFileIds)) + ON_CALL(mockBuildDependenciesStorage, fetchDependentSourceIds(sourceFileIds)) .WillByDefault(Return(sourceFileIds)); - ON_CALL(mockSymbolStorage, fetchDependentSourceIds(ElementsAre(sourceFileIds[0]))) + ON_CALL(mockBuildDependenciesStorage, fetchDependentSourceIds(ElementsAre(sourceFileIds[0]))) .WillByDefault(Return(FilePathIds{sourceFileIds[0]})); - ON_CALL(mockSymbolStorage, fetchDependentSourceIds(ElementsAre(main1PathId))) + ON_CALL(mockBuildDependenciesStorage, fetchDependentSourceIds(ElementsAre(main1PathId))) .WillByDefault(Return(FilePathIds{main1PathId})); mockCollector.setIsUsed(false); @@ -879,16 +879,16 @@ TEST_F(SymbolIndexer, UpdateProjectPartsFetchIncludedIndexingTimeStamps) Utils::LanguageVersion::CXX14, Utils::LanguageExtension::None}; - EXPECT_CALL(mockSymbolStorage, fetchIncludedIndexingTimeStamps(Eq(main1PathId))) + EXPECT_CALL(mockBuildDependenciesStorage, fetchIncludedIndexingTimeStamps(Eq(main1PathId))) .WillOnce(Return(dependentSourceTimeStamps1)); EXPECT_CALL(mockModifiedTimeChecker, isUpToDate(dependentSourceTimeStamps1)); - EXPECT_CALL(mockSymbolStorage, fetchIncludedIndexingTimeStamps(Eq(main2PathId))) + EXPECT_CALL(mockBuildDependenciesStorage, fetchIncludedIndexingTimeStamps(Eq(main2PathId))) .WillOnce(Return(dependentSourceTimeStamps2)); EXPECT_CALL(mockModifiedTimeChecker, isUpToDate(dependentSourceTimeStamps2)); EXPECT_CALL(mockCollector, fileStatuses()).WillRepeatedly(ReturnRef(fileStatuses1)); - EXPECT_CALL(mockSymbolStorage, insertOrUpdateIndexingTimeStamps(fileStatuses1)); + EXPECT_CALL(mockBuildDependenciesStorage, insertOrUpdateIndexingTimeStamps(fileStatuses1)); EXPECT_CALL(mockCollector, fileStatuses()).WillRepeatedly(ReturnRef(fileStatuses2)); - EXPECT_CALL(mockSymbolStorage, insertOrUpdateIndexingTimeStamps(fileStatuses2)); + EXPECT_CALL(mockBuildDependenciesStorage, insertOrUpdateIndexingTimeStamps(fileStatuses2)); indexer.updateProjectParts({projectPart}); } @@ -917,642 +917,6 @@ TEST_F(SymbolIndexer, DependentSourceAreUpToDate) indexer.updateProjectParts({projectPart1}); } -TEST_F(SymbolIndexer, SourcesAreWatched) -{ - using ClangBackEnd::IdPaths; - InSequence s; - FilePathIds sourcePathIds{4, 6, 8}; - - EXPECT_CALL(mockBuildDependenciesStorage, fetchPchSources(projectPart1.projectPartId)) - .WillOnce(Return(sourcePathIds)); - EXPECT_CALL(mockPathWatcher, - updateIdPaths(ElementsAre(AllOf(Field(&IdPaths::id, projectPart1.projectPartId), - Field(&IdPaths::filePathIds, sourcePathIds))))); - - indexer.updateProjectParts({projectPart1}); -} - -TEST_F(SymbolIndexer, CallSetNotifier) -{ - EXPECT_CALL(mockPathWatcher, setNotifier(_)); - - ClangBackEnd::SymbolIndexer indexer{indexerQueue, - mockSymbolStorage, - mockBuildDependenciesStorage, - mockPrecompiledHeaderStorage, - mockPathWatcher, - filePathCache, - fileStatusCache, - mockSqliteTransactionBackend, - mockProjectPartsStorage, - mockModifiedTimeChecker, - testEnvironment}; -} - -TEST_F(SymbolIndexer, PathChangedCallsFetchProjectPartArtefactInStorage) -{ - EXPECT_CALL(mockProjectPartsStorage, fetchProjectPartArtefact(sourceFileIds[0])); - EXPECT_CALL(mockProjectPartsStorage, fetchProjectPartArtefact(sourceFileIds[1])); - - indexer.pathsChanged(sourceFileIds); -} - -TEST_F(SymbolIndexer, PathChangedCallsFetchSourcePathIds) -{ - InSequence s; - - EXPECT_CALL(mockSymbolStorage, fetchDependentSourceIds(sourceFileIds)) - .WillOnce(Return(FilePathIds{2, 6, 5})); - EXPECT_CALL(mockProjectPartsStorage, fetchProjectPartArtefact(FilePathId{2})); - EXPECT_CALL(mockProjectPartsStorage, fetchProjectPartArtefact(FilePathId{6})); - EXPECT_CALL(mockProjectPartsStorage, fetchProjectPartArtefact(FilePathId{5})); - - indexer.pathsChanged(sourceFileIds); -} - -TEST_F(SymbolIndexer, PathChangedFetchIncludedIndexingTimeStamps) -{ - InSequence s; - ProjectPartContainer projectPart{1, - {"-Wno-pragma-once-outside-header"}, - {{"BAR", "1", 1}, {"FOO", "1", 2}}, - Utils::clone(systemIncludeSearchPaths), - Utils::clone(projectIncludeSearchPaths), - {header1PathId}, - {main1PathId, main2PathId}, - Utils::Language::Cxx, - Utils::LanguageVersion::CXX14, - Utils::LanguageExtension::None}; - - EXPECT_CALL(mockSymbolStorage, fetchDependentSourceIds(_)).WillOnce(Return(FilePathIds{1, 2})); - EXPECT_CALL(mockSymbolStorage, fetchIncludedIndexingTimeStamps(Eq(1))) - .WillOnce(Return(dependentSourceTimeStamps1)); - EXPECT_CALL(mockSymbolStorage, fetchIncludedIndexingTimeStamps(Eq(2))) - .WillOnce(Return(dependentSourceTimeStamps2)); - EXPECT_CALL(mockCollector, fileStatuses()).WillOnce(ReturnRef(fileStatuses1)); - EXPECT_CALL(mockSymbolStorage, insertOrUpdateIndexingTimeStamps(fileStatuses1)); - EXPECT_CALL(mockCollector, fileStatuses()).WillOnce(ReturnRef(fileStatuses2)); - EXPECT_CALL(mockSymbolStorage, insertOrUpdateIndexingTimeStamps(fileStatuses2)); - - indexer.pathsChanged({1, 3}); -} - -TEST_F(SymbolIndexer, PathChangedFetchesDependentSourceIdsFromStorage) -{ - EXPECT_CALL(mockProjectPartsStorage, fetchProjectPartArtefact(sourceFileIds[0])); - EXPECT_CALL(mockProjectPartsStorage, fetchProjectPartArtefact(sourceFileIds[1])); - - indexer.pathsChanged(sourceFileIds); -} - -TEST_F(SymbolIndexer, UpdateChangedPathCallsInOrder) -{ - InSequence s; - - EXPECT_CALL(mockSqliteTransactionBackend, deferredBegin()); - EXPECT_CALL(mockProjectPartsStorage, - fetchProjectPartArtefact(TypedEq<FilePathId>(sourceFileIds[0]))) - .WillOnce(Return(artefact)); - EXPECT_CALL(mockSqliteTransactionBackend, commit()); - EXPECT_CALL(mockPrecompiledHeaderStorage, fetchPrecompiledHeaders(Eq(artefact.projectPartId))); - EXPECT_CALL(mockCollector, - setFile(Eq(sourceFileIds[0]), - ElementsAre("clang++", - "-w", - "-DFOO", - "-DNOMINMAX", - "-x", - "c++", - "-std=c++14", - "-nostdinc", - "-nostdinc++", - "-DBAR=1", - "-DFOO=1", - "-isystem", - toNativePath(TESTDATA_DIR "/preincludes"), - "-I", - toNativePath("/project/includes"), - "-I", - toNativePath("/other/project/includes"), - "-isystem", - toNativePath(TESTDATA_DIR), - "-isystem", - toNativePath("/other/includes"), - "-isystem", - toNativePath("/includes")))); - EXPECT_CALL(mockCollector, collectSymbols()); - EXPECT_CALL(mockSqliteTransactionBackend, immediateBegin()); - EXPECT_CALL(mockSymbolStorage, addSymbolsAndSourceLocations(symbolEntries, sourceLocations)); - EXPECT_CALL(mockSqliteTransactionBackend, commit()); - - indexer.pathsChanged({sourceFileIds[0]}); -} - -TEST_F(SymbolIndexer, HandleEmptyOptionalArtifactInUpdateChangedPath) -{ - InSequence s; - - EXPECT_CALL(mockSqliteTransactionBackend, deferredBegin()); - EXPECT_CALL(mockProjectPartsStorage, fetchProjectPartArtefact(sourceFileIds[0])) - .WillOnce(Return(nullArtefact)); - EXPECT_CALL(mockSqliteTransactionBackend, commit()).Times(0); - EXPECT_CALL(mockPrecompiledHeaderStorage, fetchPrecompiledHeaders(_)).Times(0); - EXPECT_CALL(mockCollector, setFile(_, _)).Times(0); - EXPECT_CALL(mockCollector, collectSymbols()).Times(0); - EXPECT_CALL(mockSqliteTransactionBackend, immediateBegin()).Times(0); - EXPECT_CALL(mockSymbolStorage, addSymbolsAndSourceLocations(_, _)).Times(0); - EXPECT_CALL(mockSqliteTransactionBackend, commit()).Times(0); - - indexer.pathsChanged({sourceFileIds[0]}); -} - -TEST_F(SymbolIndexer, PathsChangedCallsGetsProjectAndSystemPchPathsAndHasNoError) -{ - InSequence s; - - EXPECT_CALL(mockProjectPartsStorage, - fetchProjectPartArtefact(TypedEq<FilePathId>(sourceFileIds[0]))) - .WillOnce(Return(artefact)); - EXPECT_CALL(mockPrecompiledHeaderStorage, fetchPrecompiledHeaders(Eq(artefact.projectPartId))) - .WillOnce(Return(ClangBackEnd::PchPaths{"/project/pch", "/system/pch"})); - EXPECT_CALL(mockCollector, - setFile(sourceFileIds[0], - ElementsAre("clang++", - "-w", - "-DFOO", - "-DNOMINMAX", - "-x", - "c++", - "-std=c++14", - "-nostdinc", - "-nostdinc++", - "-DBAR=1", - "-DFOO=1", - "-isystem", - toNativePath(TESTDATA_DIR "/preincludes"), - "-I", - toNativePath("/project/includes"), - "-I", - toNativePath("/other/project/includes"), - "-isystem", - toNativePath(TESTDATA_DIR), - "-isystem", - toNativePath("/other/includes"), - "-isystem", - toNativePath("/includes"), - "-Xclang", - "-include-pch", - "-Xclang", - toNativePath("/project/pch")))); - EXPECT_CALL(mockCollector, collectSymbols()).WillOnce(Return(true)); - EXPECT_CALL(mockSymbolStorage, addSymbolsAndSourceLocations(symbolEntries, sourceLocations)); - EXPECT_CALL(mockCollector, collectSymbols()).Times(0); - - indexer.pathsChanged({sourceFileIds[0]}); -} - -TEST_F(SymbolIndexer, PathsChangedCallsGetsProjectAndSystemPchPathsAndHasErrorWithProjectPch) -{ - InSequence s; - - EXPECT_CALL(mockProjectPartsStorage, - fetchProjectPartArtefact(TypedEq<FilePathId>(sourceFileIds[0]))) - .WillOnce(Return(artefact)); - EXPECT_CALL(mockPrecompiledHeaderStorage, fetchPrecompiledHeaders(Eq(artefact.projectPartId))) - .WillOnce(Return(ClangBackEnd::PchPaths{"/project/pch", "/system/pch"})); - EXPECT_CALL(mockCollector, - setFile(sourceFileIds[0], - ElementsAre("clang++", - "-w", - "-DFOO", - "-DNOMINMAX", - "-x", - "c++", - "-std=c++14", - "-nostdinc", - "-nostdinc++", - "-DBAR=1", - "-DFOO=1", - "-isystem", - toNativePath(TESTDATA_DIR "/preincludes"), - "-I", - toNativePath("/project/includes"), - "-I", - toNativePath("/other/project/includes"), - "-isystem", - toNativePath(TESTDATA_DIR), - "-isystem", - toNativePath("/other/includes"), - "-isystem", - toNativePath("/includes"), - "-Xclang", - "-include-pch", - "-Xclang", - toNativePath("/project/pch")))); - EXPECT_CALL(mockCollector, collectSymbols()).WillOnce(Return(false)); - EXPECT_CALL(mockSymbolStorage, addSymbolsAndSourceLocations(symbolEntries, sourceLocations)).Times(0); - EXPECT_CALL(mockCollector, - setFile(sourceFileIds[0], - ElementsAre("clang++", - "-w", - "-DFOO", - "-DNOMINMAX", - "-x", - "c++", - "-std=c++14", - "-nostdinc", - "-nostdinc++", - "-DBAR=1", - "-DFOO=1", - "-isystem", - toNativePath(TESTDATA_DIR "/preincludes"), - "-I", - toNativePath("/project/includes"), - "-I", - toNativePath("/other/project/includes"), - "-isystem", - toNativePath(TESTDATA_DIR), - "-isystem", - toNativePath("/other/includes"), - "-isystem", - toNativePath("/includes"), - "-Xclang", - "-include-pch", - "-Xclang", - toNativePath("/system/pch")))); - EXPECT_CALL(mockCollector, collectSymbols()).WillOnce(Return(true)); - EXPECT_CALL(mockSymbolStorage, addSymbolsAndSourceLocations(symbolEntries, sourceLocations)); - EXPECT_CALL(mockCollector, collectSymbols()).Times(0); - - indexer.pathsChanged({sourceFileIds[0]}); -} - -TEST_F(SymbolIndexer, PathsChangedCallsGetsProjectAndSystemPchPathsAndHasErrorWithProjectAndSystemPch) -{ - InSequence s; - - EXPECT_CALL(mockProjectPartsStorage, - fetchProjectPartArtefact(TypedEq<FilePathId>(sourceFileIds[0]))) - .WillOnce(Return(artefact)); - EXPECT_CALL(mockPrecompiledHeaderStorage, fetchPrecompiledHeaders(Eq(artefact.projectPartId))) - .WillOnce(Return(ClangBackEnd::PchPaths{"/project/pch", "/system/pch"})); - EXPECT_CALL(mockCollector, - setFile(sourceFileIds[0], - ElementsAre("clang++", - "-w", - "-DFOO", - "-DNOMINMAX", - "-x", - "c++", - "-std=c++14", - "-nostdinc", - "-nostdinc++", - "-DBAR=1", - "-DFOO=1", - "-isystem", - toNativePath(TESTDATA_DIR "/preincludes"), - "-I", - toNativePath("/project/includes"), - "-I", - toNativePath("/other/project/includes"), - "-isystem", - toNativePath(TESTDATA_DIR), - "-isystem", - toNativePath("/other/includes"), - "-isystem", - toNativePath("/includes"), - "-Xclang", - "-include-pch", - "-Xclang", - toNativePath("/project/pch")))); - EXPECT_CALL(mockCollector, collectSymbols()).WillOnce(Return(false)); - EXPECT_CALL(mockSymbolStorage, addSymbolsAndSourceLocations(symbolEntries, sourceLocations)).Times(0); - EXPECT_CALL(mockCollector, - setFile(sourceFileIds[0], - ElementsAre("clang++", - "-w", - "-DFOO", - "-DNOMINMAX", - "-x", - "c++", - "-std=c++14", - "-nostdinc", - "-nostdinc++", - "-DBAR=1", - "-DFOO=1", - "-isystem", - toNativePath(TESTDATA_DIR "/preincludes"), - "-I", - toNativePath("/project/includes"), - "-I", - toNativePath("/other/project/includes"), - "-isystem", - toNativePath(TESTDATA_DIR), - "-isystem", - toNativePath("/other/includes"), - "-isystem", - toNativePath("/includes"), - "-Xclang", - "-include-pch", - "-Xclang", - toNativePath("/system/pch")))); - EXPECT_CALL(mockCollector, collectSymbols()).WillOnce(Return(false)); - EXPECT_CALL(mockSymbolStorage, addSymbolsAndSourceLocations(symbolEntries, sourceLocations)).Times(0); - EXPECT_CALL(mockCollector, - setFile(sourceFileIds[0], - ElementsAre("clang++", - "-w", - "-DFOO", - "-DNOMINMAX", - "-x", - "c++", - "-std=c++14", - "-nostdinc", - "-nostdinc++", - "-DBAR=1", - "-DFOO=1", - "-isystem", - toNativePath(TESTDATA_DIR "/preincludes"), - "-I", - toNativePath("/project/includes"), - "-I", - toNativePath("/other/project/includes"), - "-isystem", - toNativePath(TESTDATA_DIR), - "-isystem", - toNativePath("/other/includes"), - "-isystem", - toNativePath("/includes")))); - EXPECT_CALL(mockCollector, collectSymbols()).WillOnce(Return(true)); - EXPECT_CALL(mockSymbolStorage, addSymbolsAndSourceLocations(symbolEntries, sourceLocations)); - - indexer.pathsChanged({sourceFileIds[0]}); -} - -TEST_F(SymbolIndexer, PathsChangedCallsGetsProjectAndSystemPchPathsAndHasOnlyError) -{ - InSequence s; - - EXPECT_CALL(mockProjectPartsStorage, - fetchProjectPartArtefact(TypedEq<FilePathId>(sourceFileIds[0]))) - .WillOnce(Return(artefact)); - EXPECT_CALL(mockPrecompiledHeaderStorage, fetchPrecompiledHeaders(Eq(artefact.projectPartId))) - .WillOnce(Return(ClangBackEnd::PchPaths{"/project/pch", "/system/pch"})); - EXPECT_CALL(mockCollector, - setFile(sourceFileIds[0], - ElementsAre("clang++", - "-w", - "-DFOO", - "-DNOMINMAX", - "-x", - "c++", - "-std=c++14", - "-nostdinc", - "-nostdinc++", - "-DBAR=1", - "-DFOO=1", - "-isystem", - toNativePath(TESTDATA_DIR "/preincludes"), - "-I", - toNativePath("/project/includes"), - "-I", - toNativePath("/other/project/includes"), - "-isystem", - toNativePath(TESTDATA_DIR), - "-isystem", - toNativePath("/other/includes"), - "-isystem", - toNativePath("/includes"), - "-Xclang", - "-include-pch", - "-Xclang", - toNativePath("/project/pch")))); - EXPECT_CALL(mockCollector, collectSymbols()).WillOnce(Return(false)); - EXPECT_CALL(mockSymbolStorage, addSymbolsAndSourceLocations(symbolEntries, sourceLocations)).Times(0); - EXPECT_CALL(mockCollector, - setFile(sourceFileIds[0], - ElementsAre("clang++", - "-w", - "-DFOO", - "-DNOMINMAX", - "-x", - "c++", - "-std=c++14", - "-nostdinc", - "-nostdinc++", - "-DBAR=1", - "-DFOO=1", - "-isystem", - toNativePath(TESTDATA_DIR "/preincludes"), - "-I", - toNativePath("/project/includes"), - "-I", - toNativePath("/other/project/includes"), - "-isystem", - toNativePath(TESTDATA_DIR), - "-isystem", - toNativePath("/other/includes"), - "-isystem", - toNativePath("/includes"), - "-Xclang", - "-include-pch", - "-Xclang", - toNativePath("/system/pch")))); - EXPECT_CALL(mockCollector, collectSymbols()).WillOnce(Return(false)); - EXPECT_CALL(mockSymbolStorage, addSymbolsAndSourceLocations(symbolEntries, sourceLocations)).Times(0); - EXPECT_CALL(mockCollector, - setFile(sourceFileIds[0], - ElementsAre("clang++", - "-w", - "-DFOO", - "-DNOMINMAX", - "-x", - "c++", - "-std=c++14", - "-nostdinc", - "-nostdinc++", - "-DBAR=1", - "-DFOO=1", - "-isystem", - toNativePath(TESTDATA_DIR "/preincludes"), - "-I", - toNativePath("/project/includes"), - "-I", - toNativePath("/other/project/includes"), - "-isystem", - toNativePath(TESTDATA_DIR), - "-isystem", - toNativePath("/other/includes"), - "-isystem", - toNativePath("/includes")))); - EXPECT_CALL(mockCollector, collectSymbols()).WillOnce(Return(false)); - EXPECT_CALL(mockSymbolStorage, addSymbolsAndSourceLocations(symbolEntries, sourceLocations)).Times(0); - - indexer.pathsChanged({sourceFileIds[0]}); -} - -TEST_F(SymbolIndexer, PathsChangedCallsGetsSystemPchPathsAndHasErrorWithProjectPch) -{ - InSequence s; - - EXPECT_CALL(mockProjectPartsStorage, - fetchProjectPartArtefact(TypedEq<FilePathId>(sourceFileIds[0]))) - .WillOnce(Return(artefact)); - EXPECT_CALL(mockPrecompiledHeaderStorage, fetchPrecompiledHeaders(Eq(artefact.projectPartId))) - .WillOnce(Return(ClangBackEnd::PchPaths{{}, "/system/pch"})); - EXPECT_CALL(mockCollector, - setFile(sourceFileIds[0], - ElementsAre("clang++", - "-w", - "-DFOO", - "-DNOMINMAX", - "-x", - "c++", - "-std=c++14", - "-nostdinc", - "-nostdinc++", - "-DBAR=1", - "-DFOO=1", - "-isystem", - toNativePath(TESTDATA_DIR "/preincludes"), - "-I", - toNativePath("/project/includes"), - "-I", - toNativePath("/other/project/includes"), - "-isystem", - toNativePath(TESTDATA_DIR), - "-isystem", - toNativePath("/other/includes"), - "-isystem", - toNativePath("/includes"), - "-Xclang", - "-include-pch", - "-Xclang", - toNativePath("/system/pch")))); - EXPECT_CALL(mockCollector, collectSymbols()).WillOnce(Return(true)); - EXPECT_CALL(mockSymbolStorage, addSymbolsAndSourceLocations(symbolEntries, sourceLocations)); - EXPECT_CALL(mockCollector, collectSymbols()).Times(0); - - indexer.pathsChanged({sourceFileIds[0]}); -} - -TEST_F(SymbolIndexer, PathsChangedCallsGetsNoPchPathsAndHasErrors) -{ - InSequence s; - - EXPECT_CALL(mockProjectPartsStorage, - fetchProjectPartArtefact(TypedEq<FilePathId>(sourceFileIds[0]))) - .WillOnce(Return(artefact)); - EXPECT_CALL(mockPrecompiledHeaderStorage, fetchPrecompiledHeaders(Eq(artefact.projectPartId))); - EXPECT_CALL(mockCollector, - setFile(sourceFileIds[0], - ElementsAre("clang++", - "-w", - "-DFOO", - "-DNOMINMAX", - "-x", - "c++", - "-std=c++14", - "-nostdinc", - "-nostdinc++", - "-DBAR=1", - "-DFOO=1", - "-isystem", - toNativePath(TESTDATA_DIR "/preincludes"), - "-I", - toNativePath("/project/includes"), - "-I", - toNativePath("/other/project/includes"), - "-isystem", - toNativePath(TESTDATA_DIR), - "-isystem", - toNativePath("/other/includes"), - "-isystem", - toNativePath("/includes")))); - EXPECT_CALL(mockCollector, collectSymbols()).WillOnce(Return(true)); - EXPECT_CALL(mockSymbolStorage, addSymbolsAndSourceLocations(symbolEntries, sourceLocations)); - EXPECT_CALL(mockCollector, collectSymbols()).Times(0); - - indexer.pathsChanged({sourceFileIds[0]}); -} - -TEST_F(SymbolIndexer, UpdateChangedPathIsUsingPrecompiledHeader) -{ - ON_CALL(mockProjectPartsStorage, fetchProjectPartArtefact(TypedEq<FilePathId>(sourceFileIds[0]))) - .WillByDefault(Return(artefact)); - ON_CALL(mockPrecompiledHeaderStorage, fetchPrecompiledHeaders(Eq(artefact.projectPartId))) - .WillByDefault(Return(pchPaths)); - std::vector<SymbolIndexerTask> symbolIndexerTask; - - EXPECT_CALL(mockCollector, - setFile(Eq(sourceFileIds[0]), - ElementsAre("clang++", - "-w", - "-DFOO", - "-DNOMINMAX", - "-x", - "c++", - "-std=c++14", - "-nostdinc", - "-nostdinc++", - "-DBAR=1", - "-DFOO=1", - "-isystem", - toNativePath(TESTDATA_DIR "/preincludes"), - "-I", - toNativePath("/project/includes"), - "-I", - toNativePath("/other/project/includes"), - "-isystem", - toNativePath(TESTDATA_DIR), - "-isystem", - toNativePath("/other/includes"), - "-isystem", - toNativePath("/includes"), - "-Xclang", - "-include-pch", - "-Xclang", - toNativePath("/project/pch")))); - - indexer.pathsChanged({sourceFileIds[0]}); -} - -TEST_F(SymbolIndexer, UpdateChangedPathIsNotUsingPrecompiledHeaderIfItNotExists) -{ - ON_CALL(mockProjectPartsStorage, fetchProjectPartArtefact(TypedEq<FilePathId>(sourceFileIds[0]))) - .WillByDefault(Return(artefact)); - std::vector<SymbolIndexerTask> symbolIndexerTask; - - EXPECT_CALL(mockCollector, - setFile(Eq(sourceFileIds[0]), - ElementsAre("clang++", - "-w", - "-DFOO", - "-DNOMINMAX", - "-x", - "c++", - "-std=c++14", - "-nostdinc", - "-nostdinc++", - "-DBAR=1", - "-DFOO=1", - "-isystem", - toNativePath(TESTDATA_DIR "/preincludes"), - "-I", - toNativePath("/project/includes"), - "-I", - toNativePath("/other/project/includes"), - "-isystem", - toNativePath(TESTDATA_DIR), - "-isystem", - toNativePath("/other/includes"), - "-isystem", - toNativePath("/includes")))); - - indexer.pathsChanged({sourceFileIds[0]}); -} - - TEST_F(SymbolIndexer, CompilerMacrosAndIncludeSearchPathsAreNotDifferent) { ON_CALL(mockProjectPartsStorage, fetchProjectPartArtefact(A<ProjectPartId>())) @@ -1660,7 +1024,8 @@ TEST_F(SymbolIndexer, PathsChangedUpdatesFileStatusCache) { auto sourceId = filePathId(TESTDATA_DIR "/symbolindexer_pathChanged.cpp"); ON_CALL(mockFileSystem, lastModified(Eq(sourceId))).WillByDefault(Return(65)); - ON_CALL(mockSymbolStorage, fetchDependentSourceIds(_)).WillByDefault(Return(FilePathIds{sourceId})); + ON_CALL(mockBuildDependenciesStorage, fetchDependentSourceIds(_)) + .WillByDefault(Return(FilePathIds{sourceId})); indexer.pathsChanged({sourceId}); diff --git a/tests/unit/unittest/symbolstorage-test.cpp b/tests/unit/unittest/symbolstorage-test.cpp index a29b7f92aa..c480296f12 100644 --- a/tests/unit/unittest/symbolstorage-test.cpp +++ b/tests/unit/unittest/symbolstorage-test.cpp @@ -69,10 +69,6 @@ protected: MockSqliteWriteStatement &insertNewLocationsInLocationsStatement = storage.insertNewLocationsInLocationsStatement; MockSqliteWriteStatement &deleteNewSymbolsTableStatement = storage.deleteNewSymbolsTableStatement; MockSqliteWriteStatement &deleteNewLocationsTableStatement = storage.deleteNewLocationsTableStatement; - MockSqliteWriteStatement &inserOrUpdateIndexingTimesStampStatement = storage.inserOrUpdateIndexingTimesStampStatement; - MockSqliteReadStatement &fetchIndexingTimeStampsStatement = storage.fetchIndexingTimeStampsStatement; - MockSqliteReadStatement &fetchIncludedIndexingTimeStampsStatement = storage.fetchIncludedIndexingTimeStampsStatement; - MockSqliteReadStatement &fetchDependentSourceIdsStatement = storage.fetchDependentSourceIdsStatement; SymbolEntries symbolEntries{{1, {"functionUSR", "function", SymbolKind::Function}}, {2, {"function2USR", "function2", SymbolKind::Function}}}; SourceLocationEntries sourceLocations{{1, 3, {42, 23}, SourceLocationKind::Declaration}, @@ -192,145 +188,4 @@ TEST_F(SymbolStorage, AddTablesInConstructor) Storage storage{mockDatabase}; } -TEST_F(SymbolStorage, FetchIndexingTimeStampsIsBusy) -{ - InSequence s; - - EXPECT_CALL(mockDatabase, deferredBegin()); - EXPECT_CALL(fetchIndexingTimeStampsStatement, valuesReturnSourceTimeStamps(1024)) - .WillOnce(Throw(Sqlite::StatementIsBusy{""})); - EXPECT_CALL(mockDatabase, rollback()); - EXPECT_CALL(mockDatabase, deferredBegin()); - EXPECT_CALL(fetchIndexingTimeStampsStatement, valuesReturnSourceTimeStamps(1024)); - EXPECT_CALL(mockDatabase, commit()); - - storage.fetchIndexingTimeStamps(); -} - -TEST_F(SymbolStorage, InsertIndexingTimeStamp) -{ - ClangBackEnd::FileStatuses fileStatuses{{1, 0, 34}, {2, 0, 37}}; - - EXPECT_CALL(inserOrUpdateIndexingTimesStampStatement, write(TypedEq<int>(1), TypedEq<int>(34))); - EXPECT_CALL(inserOrUpdateIndexingTimesStampStatement, write(TypedEq<int>(2), TypedEq<int>(37))); - - storage.insertOrUpdateIndexingTimeStamps(fileStatuses); -} - -TEST_F(SymbolStorage, InsertIndexingTimeStampsIsBusy) -{ - InSequence s; - - EXPECT_CALL(mockDatabase, immediateBegin()).WillOnce(Throw(Sqlite::StatementIsBusy{""})); - EXPECT_CALL(mockDatabase, immediateBegin()); - EXPECT_CALL(inserOrUpdateIndexingTimesStampStatement, write(TypedEq<int>(1), TypedEq<int>(34))); - EXPECT_CALL(inserOrUpdateIndexingTimesStampStatement, write(TypedEq<int>(2), TypedEq<int>(34))); - EXPECT_CALL(mockDatabase, commit()); - - storage.insertOrUpdateIndexingTimeStamps({1, 2}, 34); -} - -TEST_F(SymbolStorage, FetchIncludedIndexingTimeStampsIsBusy) -{ - InSequence s; - - EXPECT_CALL(mockDatabase, deferredBegin()); - EXPECT_CALL(fetchIncludedIndexingTimeStampsStatement, - valuesReturnSourceTimeStamps(1024, TypedEq<int>(1))) - .WillOnce(Throw(Sqlite::StatementIsBusy{""})); - EXPECT_CALL(mockDatabase, rollback()); - EXPECT_CALL(mockDatabase, deferredBegin()); - EXPECT_CALL(fetchIncludedIndexingTimeStampsStatement, - valuesReturnSourceTimeStamps(1024, TypedEq<int>(1))); - EXPECT_CALL(mockDatabase, commit()); - - storage.fetchIncludedIndexingTimeStamps(1); -} - -TEST_F(SymbolStorage, FetchDependentSourceIdsIsBusy) -{ - InSequence s; - - EXPECT_CALL(mockDatabase, deferredBegin()); - EXPECT_CALL(fetchDependentSourceIdsStatement, valuesReturnFilePathIds(1024, TypedEq<int>(3))); - EXPECT_CALL(fetchDependentSourceIdsStatement, valuesReturnFilePathIds(1024, TypedEq<int>(2))) - .WillOnce(Throw(Sqlite::StatementIsBusy{""})); - EXPECT_CALL(mockDatabase, rollback()); - EXPECT_CALL(mockDatabase, deferredBegin()); - EXPECT_CALL(fetchDependentSourceIdsStatement, valuesReturnFilePathIds(1024, TypedEq<int>(3))); - EXPECT_CALL(fetchDependentSourceIdsStatement, valuesReturnFilePathIds(1024, TypedEq<int>(2))); - EXPECT_CALL(fetchDependentSourceIdsStatement, valuesReturnFilePathIds(1024, TypedEq<int>(7))); - EXPECT_CALL(mockDatabase, commit()); - - storage.fetchDependentSourceIds({3, 2, 7}); -} - -class SymbolStorageSlow : public testing::Test -{ -protected: - Sqlite::Database database{":memory:", Sqlite::JournalMode::Memory}; - ClangBackEnd::RefactoringDatabaseInitializer<Sqlite::Database> databaseInitializer{database}; - ClangBackEnd::SymbolStorage<> storage{database}; - ClangBackEnd::BuildDependenciesStorage<> buildDependenciesStorage{database}; -}; - -TEST_F(SymbolStorageSlow, InsertIndexingTimeStamps) -{ - storage.insertOrUpdateIndexingTimeStamps({1, 2}, 34); - - ASSERT_THAT(storage.fetchIndexingTimeStamps(), - ElementsAre(SourceTimeStamp{1, 34}, SourceTimeStamp{2, 34})); -} - -TEST_F(SymbolStorageSlow, UpdateIndexingTimeStamps) -{ - storage.insertOrUpdateIndexingTimeStamps({1, 2}, 34); - - storage.insertOrUpdateIndexingTimeStamps({1}, 37); - - ASSERT_THAT(storage.fetchIndexingTimeStamps(), - ElementsAre(SourceTimeStamp{1, 37}, SourceTimeStamp{2, 34})); -} - -TEST_F(SymbolStorageSlow, InsertIndexingTimeStamp) -{ - storage.insertOrUpdateIndexingTimeStamps({{1, 0, 34}, {2, 0, 37}}); - - ASSERT_THAT(storage.fetchIndexingTimeStamps(), - ElementsAre(SourceTimeStamp{1, 34}, SourceTimeStamp{2, 37})); -} - -TEST_F(SymbolStorageSlow, UpdateIndexingTimeStamp) -{ - storage.insertOrUpdateIndexingTimeStamps({{1, 0, 34}, {2, 0, 34}}); - - storage.insertOrUpdateIndexingTimeStamps({{2, 0, 37}}); - - ASSERT_THAT(storage.fetchIndexingTimeStamps(), - ElementsAre(SourceTimeStamp{1, 34}, SourceTimeStamp{2, 37})); -} - -TEST_F(SymbolStorageSlow, FetchIncludedIndexingTimeStamps) -{ - storage.insertOrUpdateIndexingTimeStamps({1, 2, 3, 4, 5}, 34); - buildDependenciesStorage.insertOrUpdateSourceDependencies({{1, 2}, {1, 3}, {2, 3}, {3, 4}, {5, 3}}); - - auto timeStamps = storage.fetchIncludedIndexingTimeStamps(1); - - ASSERT_THAT(timeStamps, - ElementsAre(SourceTimeStamp{1, 34}, - SourceTimeStamp{2, 34}, - SourceTimeStamp{3, 34}, - SourceTimeStamp{4, 34})); -} - -TEST_F(SymbolStorageSlow, FetchDependentSourceIds) -{ - buildDependenciesStorage.insertOrUpdateSourceDependencies( - {{1, 2}, {1, 3}, {2, 3}, {4, 2}, {5, 6}, {7, 6}}); - - auto sourceIds = storage.fetchDependentSourceIds({3, 2, 7}); - - ASSERT_THAT(sourceIds, ElementsAre(FilePathId{1}, FilePathId{4}, FilePathId{7})); -} } // namespace diff --git a/tests/unit/unittest/unittest.pro b/tests/unit/unittest/unittest.pro index 2989331ebe..27a8ee1947 100644 --- a/tests/unit/unittest/unittest.pro +++ b/tests/unit/unittest/unittest.pro @@ -196,7 +196,6 @@ SOURCES += \ sourcerangeextractor-test.cpp \ symbolindexing-test.cpp \ symbolscollector-test.cpp \ - symbolfinder-test.cpp \ testclangtool.cpp \ usedmacrocollector-test.cpp \ builddependencycollector-test.cpp diff --git a/tests/unit/unittest/usedmacrofilter-test.cpp b/tests/unit/unittest/usedmacrofilter-test.cpp index 85e1bb59b5..0e6be5680e 100644 --- a/tests/unit/unittest/usedmacrofilter-test.cpp +++ b/tests/unit/unittest/usedmacrofilter-test.cpp @@ -97,8 +97,14 @@ TEST_F(UsedMacroFilter, Sources) { ClangBackEnd::UsedMacroFilter filter(sources, usedMacros, compileMacros); - ASSERT_THAT(filter.sources, - ElementsAre(FilePathId{2}, FilePathId{3}, FilePathId{4}, FilePathId{5})); + ASSERT_THAT(filter.sources, ElementsAre(FilePathId{6})); +} + +TEST_F(UsedMacroFilter, UserIncludes) +{ + ClangBackEnd::UsedMacroFilter filter(sources, usedMacros, compileMacros); + + ASSERT_THAT(filter.userIncludes, ElementsAre(FilePathId{1})); } TEST_F(UsedMacroFilter, SystemUsedMacros) |