aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEike Ziller <eike.ziller@qt.io>2021-10-21 09:13:03 +0200
committerEike Ziller <eike.ziller@qt.io>2021-10-21 09:13:03 +0200
commitbb9774de92dd2c8da85c5231ca5646b078cb42a3 (patch)
treee43470cf6f3a7c965b7dc8a349593dadd03ee65e
parentf41bebc843a8b4ab1ab29562ba200b032b5ab5ac (diff)
parent5377253612801b2f92e0b55e40c3ce0dd2574b09 (diff)
Merge remote-tracking branch 'origin/6.0'
Conflicts: cmake/QtCreatorIDEBranding.cmake qbs/modules/qtc/qtc.qbs qtcreator_ide_branding.pri Change-Id: If8baed5564470e550a0ba5c7720915217eec2412
-rw-r--r--.github/workflows/build_cmake.yml12
-rw-r--r--CMakeLists.txt9
-rw-r--r--doc/qtcreator/config/qtcreator-project.qdocconf17
-rw-r--r--doc/qtcreator/images/extraimages/qtcreator-extraimages.qdocconf12
-rw-r--r--doc/qtcreator/images/qml-export-gimp.pngbin96879 -> 0 bytes
-rw-r--r--doc/qtcreator/images/qml-observer-context-menu.pngbin44145 -> 0 bytes
-rw-r--r--doc/qtcreator/images/qmldesigner-backends-add.pngbin6976 -> 0 bytes
-rw-r--r--doc/qtcreator/images/qmldesigner-backends.pngbin3740 -> 0 bytes
-rw-r--r--doc/qtcreator/images/qmldesigner-new-project.pngbin18298 -> 17167 bytes
-rw-r--r--doc/qtcreator/images/qtcreator-iso-icon-browser.pngbin23508 -> 0 bytes
-rw-r--r--doc/qtcreator/images/qtcreator-live-preview.pngbin103145 -> 46355 bytes
-rw-r--r--doc/qtcreator/images/qtcreator-new-qt-quick-project-wizard.pngbin33979 -> 17426 bytes
-rw-r--r--doc/qtcreator/images/qtcreator-new-subproject.pngbin15964 -> 17167 bytes
-rw-r--r--doc/qtcreator/images/qtcreator-qt-quick-editors.pngbin118018 -> 0 bytes
-rw-r--r--doc/qtcreator/src/debugger/qtquick-debugging.qdoc7
-rw-r--r--doc/qtcreator/src/editors/creator-code-syntax.qdoc22
-rw-r--r--doc/qtcreator/src/editors/creator-quick-fixes.qdoc6
-rw-r--r--doc/qtcreator/src/external-resources/external-resources-qds.qdoc43
-rw-r--r--doc/qtcreator/src/external-resources/external-resources.qdoc8
-rw-r--r--doc/qtcreator/src/howto/creator-keyboard-shortcuts.qdoc4
-rw-r--r--doc/qtcreator/src/howto/creator-only/qtcreator-faq.qdoc2
-rw-r--r--doc/qtcreator/src/howto/creator-telemetry.qdoc66
-rw-r--r--doc/qtcreator/src/overview/creator-only/creator-commercial-overview.qdoc3
-rw-r--r--doc/qtcreator/src/overview/creator-only/creator-design-overview.qdoc11
-rw-r--r--doc/qtcreator/src/overview/creator-only/creator-issues.qdoc11
-rw-r--r--doc/qtcreator/src/overview/creator-only/creator-overview.qdoc4
-rw-r--r--doc/qtcreator/src/overview/creator-only/creator-tutorials.qdoc2
-rw-r--r--doc/qtcreator/src/projects/creator-only/creator-projects-creating.qdoc19
-rw-r--r--doc/qtcreator/src/python/creator-python-project.qdocinc6
-rw-r--r--doc/qtcreator/src/qtcreator-toc.qdoc100
-rw-r--r--doc/qtcreator/src/qtquick/creator-only/qtquick-app-development.qdoc77
-rw-r--r--doc/qtcreator/src/qtquick/creator-only/qtquick-connection-editor-backend.qdoc73
-rw-r--r--doc/qtcreator/src/qtquick/creator-only/qtquick-creating.qdoc73
-rw-r--r--doc/qtcreator/src/qtquick/creator-only/qtquick-iso-icon-browser.qdoc77
-rw-r--r--doc/qtcreator/src/qtquick/creator-only/qtquick-tutorial-create-empty-project.qdocinc7
-rw-r--r--doc/qtcreator/src/qtquick/qtquick-from-qmlproject-to-pro.qdoc27
-rw-r--r--doc/qtcreator/src/qtquick/qtquick-live-preview-desktop.qdoc15
-rw-r--r--doc/qtcreator/src/qtquick/qtquick-live-preview.qdoc7
-rw-r--r--doc/qtcreator/src/qtquick/qtquick-modules-with-plugins.qdoc68
-rw-r--r--doc/qtcreator/src/qtquick/qtquick-toolbars.qdoc18
-rw-r--r--doc/qtcreator/src/qtquick/qtquick-ui-forms.qdoc19
-rw-r--r--doc/qtcreator/src/user-interface/creator-file-system-view.qdoc2
-rw-r--r--doc/qtcreator/src/user-interface/creator-open-documents-view.qdoc9
-rw-r--r--doc/qtcreator/src/user-interface/creator-projects-view.qdoc10
-rw-r--r--doc/qtcreator/src/user-interface/creator-ui.qdoc5
-rw-r--r--doc/qtcreator/src/user-interface/creator-views.qdoc6
-rw-r--r--doc/qtcreator/src/widgets/creator-faq-qtdesigner.qdocinc8
-rw-r--r--doc/qtcreator/src/widgets/qtdesigner-overview.qdoc2
-rw-r--r--doc/qtdesignstudio/src/components/qtquick-animation-types.qdoc (renamed from doc/qtcreator/src/qtquick/qtquick-animation-types.qdoc)0
-rw-r--r--doc/qtdesignstudio/src/components/qtquick-buttons.qdoc (renamed from doc/qtcreator/src/qtquick/qtquick-buttons.qdoc)0
-rw-r--r--doc/qtdesignstudio/src/components/qtquick-component-context-menu.qdocinc (renamed from doc/qtcreator/src/qtquick/qtquick-component-context-menu.qdocinc)0
-rw-r--r--doc/qtdesignstudio/src/components/qtquick-component-instances.qdoc (renamed from doc/qtcreator/src/qtquick/library/qtquick-component-instances.qdoc)0
-rw-r--r--doc/qtdesignstudio/src/components/qtquick-components-custom.qdoc (renamed from doc/qtcreator/src/qtquick/library/qtquick-components-custom.qdoc)0
-rw-r--r--doc/qtdesignstudio/src/components/qtquick-components.qdoc (renamed from doc/qtcreator/src/qtquick/qtquick-components.qdoc)0
-rw-r--r--doc/qtdesignstudio/src/components/qtquick-controls.qdoc (renamed from doc/qtcreator/src/qtquick/library/qtquick-controls.qdoc)0
-rw-r--r--doc/qtdesignstudio/src/components/qtquick-data-models.qdoc (renamed from doc/qtcreator/src/qtquick/library/qtquick-data-models.qdoc)0
-rw-r--r--doc/qtdesignstudio/src/components/qtquick-images.qdoc (renamed from doc/qtcreator/src/qtquick/library/qtquick-images.qdoc)0
-rw-r--r--doc/qtdesignstudio/src/components/qtquick-pathview-editor.qdocinc (renamed from doc/qtcreator/src/qtquick/library/qtquick-pathview-editor.qdocinc)0
-rw-r--r--doc/qtdesignstudio/src/components/qtquick-positioning.qdoc (renamed from doc/qtcreator/src/qtquick/qtquick-positioning.qdoc)0
-rw-r--r--doc/qtdesignstudio/src/components/qtquick-preset-components.qdoc (renamed from doc/qtcreator/src/qtquick/library/qtquick-preset-components.qdoc)0
-rw-r--r--doc/qtdesignstudio/src/components/qtquick-shapes.qdoc (renamed from doc/qtcreator/src/qtquick/library/qtquick-shapes.qdoc)0
-rw-r--r--doc/qtdesignstudio/src/components/qtquick-text.qdoc (renamed from doc/qtcreator/src/qtquick/library/qtquick-text.qdoc)0
-rw-r--r--doc/qtdesignstudio/src/components/qtquick-user-interaction-methods.qdoc (renamed from doc/qtcreator/src/qtquick/library/qtquick-user-interaction-methods.qdoc)0
-rw-r--r--doc/qtdesignstudio/src/overviews/qtdesignstudio-simulation-overview.qdoc (renamed from doc/qtcreator/src/qtquick/qtdesignstudio-simulation-overview.qdoc)9
-rw-r--r--doc/qtdesignstudio/src/overviews/qtquick-animation-overview.qdoc (renamed from doc/qtcreator/src/qtquick/qtquick-animation-overview.qdoc)0
-rw-r--r--doc/qtdesignstudio/src/overviews/qtquick-annotations.qdoc (renamed from doc/qtcreator/src/qtquick/qtquick-annotations.qdoc)0
-rw-r--r--doc/qtdesignstudio/src/overviews/qtquick-creating-ui-logic.qdoc (renamed from doc/qtcreator/src/qtquick/qtquick-creating-ui-logic.qdoc)0
-rw-r--r--doc/qtdesignstudio/src/overviews/qtquick-export.qdoc (renamed from doc/qtcreator/src/qtquick/qtquick-export.qdoc)0
-rw-r--r--doc/qtdesignstudio/src/overviews/qtquick-fonts.qdoc (renamed from doc/qtcreator/src/qtquick/qtquick-fonts.qdoc)0
-rw-r--r--doc/qtdesignstudio/src/overviews/qtquick-motion-design.qdoc (renamed from doc/qtcreator/src/qtquick/qtquick-motion-design.qdoc)0
-rw-r--r--doc/qtdesignstudio/src/overviews/qtquick-optimizing-designs.qdoc (renamed from doc/qtcreator/src/qtquick/qtquick-optimizing-designs.qdoc)0
-rw-r--r--doc/qtdesignstudio/src/overviews/qtquick-placeholder-data.qdoc (renamed from doc/qtcreator/src/qtquick/qtquick-placeholder-data.qdoc)7
-rw-r--r--doc/qtdesignstudio/src/overviews/qtquick-production-quality-animation.qdoc (renamed from doc/qtcreator/src/qtquick/qtquick-production-quality-animation.qdoc)0
-rw-r--r--doc/qtdesignstudio/src/overviews/qtquick-prototyping.qdoc (renamed from doc/qtcreator/src/qtquick/qtquick-prototyping.qdoc)0
-rw-r--r--doc/qtdesignstudio/src/overviews/qtquick-uis.qdoc (renamed from doc/qtcreator/src/qtquick/qtquick-uis.qdoc)0
-rw-r--r--doc/qtdesignstudio/src/overviews/studio-crashpad.qdoc59
-rw-r--r--doc/qtdesignstudio/src/overviews/studio-user-feedback.qdoc52
-rw-r--r--doc/qtdesignstudio/src/qtbridge/qtbridge-ps-using.qdoc2
-rw-r--r--doc/qtdesignstudio/src/qtdesignstudio-packaging.qdoc2
-rw-r--r--doc/qtdesignstudio/src/qtquick3d-editor/qtdesignstudio-optimized-3d-scenes.qdoc (renamed from doc/qtcreator/src/qtquick/qtdesignstudio-optimized-3d-scenes.qdoc)0
-rw-r--r--doc/qtdesignstudio/src/views/creator-logical-operators.qdocinc (renamed from doc/qtcreator/src/qtquick/creator-logical-operators.qdocinc)0
-rw-r--r--doc/qtdesignstudio/src/views/qtquick-adding-dynamics.qdoc (renamed from doc/qtcreator/src/qtquick/qtquick-adding-dynamics.qdoc)0
-rw-r--r--doc/qtdesignstudio/src/views/qtquick-connection-editor-bindings.qdoc (renamed from doc/qtcreator/src/qtquick/qtquick-connection-editor-bindings.qdoc)0
-rw-r--r--doc/qtdesignstudio/src/views/qtquick-connection-editor-properties.qdoc (renamed from doc/qtcreator/src/qtquick/qtquick-connection-editor-properties.qdoc)0
-rw-r--r--doc/qtdesignstudio/src/views/qtquick-connection-editor-signals.qdoc (renamed from doc/qtcreator/src/qtquick/qtquick-connection-editor-signals.qdoc)0
-rw-r--r--doc/qtdesignstudio/src/views/qtquick-connection-editor.qdoc (renamed from doc/qtcreator/src/qtquick/qtquick-connection-editor.qdoc)0
-rw-r--r--doc/qtdesignstudio/src/views/qtquick-connection-view.qdoc (renamed from doc/qtcreator/src/qtquick/qtquick-connection-view.qdoc)0
-rw-r--r--doc/qtdesignstudio/src/views/qtquick-curve-editor.qdoc (renamed from doc/qtcreator/src/qtquick/qtquick-curve-editor.qdoc)0
-rw-r--r--doc/qtdesignstudio/src/views/qtquick-designer.qdoc (renamed from doc/qtcreator/src/qtquick/qtquick-designer.qdoc)0
-rw-r--r--doc/qtdesignstudio/src/views/qtquick-easing-curve-editor.qdoc (renamed from doc/qtcreator/src/qtquick/qtquick-easing-curve-editor.qdoc)0
-rw-r--r--doc/qtdesignstudio/src/views/qtquick-form-editor.qdoc (renamed from doc/qtcreator/src/qtquick/qtquick-form-editor.qdoc)0
-rw-r--r--doc/qtdesignstudio/src/views/qtquick-library.qdoc (renamed from doc/qtcreator/src/qtquick/qtquick-library.qdoc)0
-rw-r--r--doc/qtdesignstudio/src/views/qtquick-navigator.qdoc (renamed from doc/qtcreator/src/qtquick/qtquick-navigator.qdoc)0
-rw-r--r--doc/qtdesignstudio/src/views/qtquick-properties-view.qdoc (renamed from doc/qtcreator/src/qtquick/qtquick-properties-view.qdoc)0
-rw-r--r--doc/qtdesignstudio/src/views/qtquick-properties.qdoc (renamed from doc/qtcreator/src/qtquick/qtquick-properties.qdoc)0
-rw-r--r--doc/qtdesignstudio/src/views/qtquick-states-view.qdoc (renamed from doc/qtcreator/src/qtquick/qtquick-states-view.qdoc)0
-rw-r--r--doc/qtdesignstudio/src/views/qtquick-states.qdoc (renamed from doc/qtcreator/src/qtquick/qtquick-states.qdoc)0
-rw-r--r--doc/qtdesignstudio/src/views/qtquick-text-editor.qdoc (renamed from doc/qtcreator/src/qtquick/qtquick-text-editor.qdoc)0
-rw-r--r--doc/qtdesignstudio/src/views/qtquick-timeline-view.qdoc (renamed from doc/qtcreator/src/qtquick/qtquick-timeline-view.qdoc)0
-rw-r--r--doc/qtdesignstudio/src/views/qtquick-timeline.qdoc (renamed from doc/qtcreator/src/qtquick/qtquick-timeline.qdoc)0
-rw-r--r--doc/qtdesignstudio/src/views/qtquick-transition-editor.qdoc (renamed from doc/qtcreator/src/qtquick/qtquick-transition-editor.qdoc)0
-rw-r--r--share/qtcreator/qml/qmlpuppet/mockfiles/qt6/AdjustableArrow.qml2
-rw-r--r--share/qtcreator/qml/qmlpuppet/mockfiles/qt6/AreaLightHandle.qml1
-rw-r--r--share/qtcreator/qml/qmlpuppet/mockfiles/qt6/CameraFrustum.qml1
-rw-r--r--share/qtcreator/qml/qmlpuppet/mockfiles/qt6/DirectionalDraggable.qml1
-rw-r--r--share/qtcreator/qml/qmlpuppet/mockfiles/qt6/EditView3D.qml3
-rw-r--r--share/qtcreator/qml/qmlpuppet/mockfiles/qt6/FadeHandle.qml1
-rw-r--r--share/qtcreator/qml/qmlpuppet/mockfiles/qt6/HelperGrid.qml4
-rw-r--r--share/qtcreator/qml/qmlpuppet/mockfiles/qt6/LightModel.qml1
-rw-r--r--share/qtcreator/qml/qmlpuppet/mockfiles/qt6/Line3D.qml1
-rw-r--r--share/qtcreator/qml/qmlpuppet/mockfiles/qt6/MaterialNodeView.qml1
-rw-r--r--share/qtcreator/qml/qmlpuppet/mockfiles/qt6/ModelNodeView.qml1
-rw-r--r--share/qtcreator/qml/qmlpuppet/mockfiles/qt6/PlanarDraggable.qml1
-rw-r--r--share/qtcreator/qml/qmlpuppet/mockfiles/qt6/RotateGizmo.qml1
-rw-r--r--share/qtcreator/qml/qmlpuppet/mockfiles/qt6/RotateRing.qml1
-rw-r--r--share/qtcreator/qml/qmlpuppet/mockfiles/qt6/ScaleGizmo.qml1
-rw-r--r--share/qtcreator/qml/qmlpuppet/mockfiles/qt6/ScaleRod.qml1
-rw-r--r--share/qtcreator/qml/qmlpuppet/mockfiles/qt6/SelectionBox.qml1
-rw-r--r--share/qtcreator/qml/qmlpuppet/mockfiles/qt6/SpotLightHandle.qml1
-rw-r--r--share/qtcreator/qml/qmlpuppet/qml2puppet/editor3d/generalhelper.cpp29
-rw-r--r--share/qtcreator/qml/qmlpuppet/qml2puppet/editor3d/generalhelper.h3
-rw-r--r--share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5informationnodeinstanceserver.cpp4
-rw-r--r--share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5nodeinstanceserver.cpp42
-rw-r--r--share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5nodeinstanceserver.h2
-rw-r--r--share/qtcreator/qml/qmlpuppet/qml2puppet/instances/quickitemnodeinstance.cpp37
-rw-r--r--share/qtcreator/qml/qmlpuppet/qml2puppet/instances/quickitemnodeinstance.h1
-rw-r--r--share/qtcreator/qml/qmlpuppet/qml2puppet/instances/servernodeinstance.cpp27
-rw-r--r--share/qtcreator/qml/qmlpuppet/qml2puppet/instances/servernodeinstance.h11
-rw-r--r--share/qtcreator/qmldesigner/itemLibraryQmlSources/ItemsView.qml61
-rw-r--r--share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/ExtendedFunctionLogic.qml1
-rw-r--r--share/qtcreator/qmldesigner/statesEditorQmlSources/StatesDelegate.qml2
-rw-r--r--src/CMakeLists.txt3
-rw-r--r--src/libs/3rdparty/syntax-highlighting/.git-blame-ignore-revs4
-rw-r--r--src/libs/3rdparty/syntax-highlighting/.gitignore11
-rw-r--r--src/libs/3rdparty/syntax-highlighting/.gitlab-ci.yml5
-rw-r--r--src/libs/3rdparty/syntax-highlighting/.kde-ci.yml7
-rw-r--r--src/libs/3rdparty/syntax-highlighting/CMakeLists.txt4
-rw-r--r--src/libs/3rdparty/syntax-highlighting/README.md43
-rw-r--r--src/libs/3rdparty/syntax-highlighting/autogenerated/autogenerated.pri3
-rw-r--r--src/libs/3rdparty/syntax-highlighting/autogenerated/ksyntaxhighlighting_version.h6
-rw-r--r--src/libs/3rdparty/syntax-highlighting/autogenerated/src/lib/WildcardMatcher1
-rw-r--r--src/libs/3rdparty/syntax-highlighting/autogenerated/src/lib/ksyntaxhighlighting_export.h218
-rw-r--r--src/libs/3rdparty/syntax-highlighting/data/CMakeLists.txt11
-rw-r--r--src/libs/3rdparty/syntax-highlighting/data/generators/cmake.xml.tpl2
-rw-r--r--src/libs/3rdparty/syntax-highlighting/data/generators/cmake.yaml231
-rw-r--r--src/libs/3rdparty/syntax-highlighting/data/generators/generate-doxygenlua.pl42
-rw-r--r--src/libs/3rdparty/syntax-highlighting/data/generators/generate-php.pl1
-rw-r--r--src/libs/3rdparty/syntax-highlighting/data/generators/generate-spdx-syntax.py67
-rw-r--r--src/libs/3rdparty/syntax-highlighting/data/generators/spdx-comments.xml.tpl91
-rw-r--r--src/libs/3rdparty/syntax-highlighting/data/syntax/bash.xml120
-rw-r--r--src/libs/3rdparty/syntax-highlighting/data/syntax/cmake.xml155
-rw-r--r--src/libs/3rdparty/syntax-highlighting/data/syntax/doxygen.xml4
-rw-r--r--src/libs/3rdparty/syntax-highlighting/data/syntax/ini.xml19
-rw-r--r--src/libs/3rdparty/syntax-highlighting/data/syntax/java.xml4
-rw-r--r--src/libs/3rdparty/syntax-highlighting/data/syntax/markdown.xml33
-rw-r--r--src/libs/3rdparty/syntax-highlighting/data/syntax/perl.xml13
-rw-r--r--src/libs/3rdparty/syntax-highlighting/data/syntax/python.xml361
-rw-r--r--src/libs/3rdparty/syntax-highlighting/data/syntax/xml.xml19
-rw-r--r--src/libs/3rdparty/syntax-highlighting/data/themes/ayu-dark.theme8
-rw-r--r--src/libs/3rdparty/syntax-highlighting/data/themes/ayu-light.theme8
-rw-r--r--src/libs/3rdparty/syntax-highlighting/data/themes/ayu-mirage.theme8
-rw-r--r--src/libs/3rdparty/syntax-highlighting/data/themes/breeze-dark.theme4
-rw-r--r--src/libs/3rdparty/syntax-highlighting/data/themes/breeze-light.theme4
-rw-r--r--src/libs/3rdparty/syntax-highlighting/data/themes/dracula.theme6
-rw-r--r--src/libs/3rdparty/syntax-highlighting/data/themes/falcon.theme184
-rw-r--r--src/libs/3rdparty/syntax-highlighting/data/themes/github-dark.theme6
-rw-r--r--src/libs/3rdparty/syntax-highlighting/data/themes/github-light.theme6
-rw-r--r--src/libs/3rdparty/syntax-highlighting/data/themes/gruvbox-dark.theme6
-rw-r--r--src/libs/3rdparty/syntax-highlighting/data/themes/gruvbox-light.theme6
-rw-r--r--src/libs/3rdparty/syntax-highlighting/data/themes/monokai.theme6
-rw-r--r--src/libs/3rdparty/syntax-highlighting/data/themes/nord.theme8
-rw-r--r--src/libs/3rdparty/syntax-highlighting/data/themes/printing.theme4
-rw-r--r--src/libs/3rdparty/syntax-highlighting/data/themes/solarized-dark.theme6
-rw-r--r--src/libs/3rdparty/syntax-highlighting/data/themes/solarized-light.theme6
-rw-r--r--src/libs/3rdparty/syntax-highlighting/data/themes/theme-data.qrc1
-rw-r--r--src/libs/3rdparty/syntax-highlighting/data/themes/vim-dark.theme6
-rw-r--r--src/libs/3rdparty/syntax-highlighting/metainfo.yaml2
-rw-r--r--src/libs/3rdparty/syntax-highlighting/src/cli/kate-syntax-highlighter.cpp14
-rw-r--r--src/libs/3rdparty/syntax-highlighting/src/indexer/CMakeLists.txt3
-rw-r--r--src/libs/3rdparty/syntax-highlighting/src/indexer/katehighlightingindexer.cpp438
-rw-r--r--src/libs/3rdparty/syntax-highlighting/src/lib/CMakeLists.txt27
-rw-r--r--src/libs/3rdparty/syntax-highlighting/src/lib/abstracthighlighter.cpp50
-rw-r--r--src/libs/3rdparty/syntax-highlighting/src/lib/abstracthighlighter.h13
-rw-r--r--src/libs/3rdparty/syntax-highlighting/src/lib/ansihighlighter.cpp102
-rw-r--r--src/libs/3rdparty/syntax-highlighting/src/lib/context.cpp17
-rw-r--r--src/libs/3rdparty/syntax-highlighting/src/lib/contextswitch.cpp9
-rw-r--r--src/libs/3rdparty/syntax-highlighting/src/lib/definition.cpp107
-rw-r--r--src/libs/3rdparty/syntax-highlighting/src/lib/definition.h28
-rw-r--r--src/libs/3rdparty/syntax-highlighting/src/lib/definitiondownloader.cpp18
-rw-r--r--src/libs/3rdparty/syntax-highlighting/src/lib/definitionref_p.h4
-rw-r--r--src/libs/3rdparty/syntax-highlighting/src/lib/format.cpp33
-rw-r--r--src/libs/3rdparty/syntax-highlighting/src/lib/htmlhighlighter.cpp39
-rw-r--r--src/libs/3rdparty/syntax-highlighting/src/lib/keywordlist.cpp31
-rw-r--r--src/libs/3rdparty/syntax-highlighting/src/lib/repository.cpp191
-rw-r--r--src/libs/3rdparty/syntax-highlighting/src/lib/repository.h10
-rw-r--r--src/libs/3rdparty/syntax-highlighting/src/lib/repository_p.h2
-rw-r--r--src/libs/3rdparty/syntax-highlighting/src/lib/rule.cpp295
-rw-r--r--src/libs/3rdparty/syntax-highlighting/src/lib/rule_p.h74
-rw-r--r--src/libs/3rdparty/syntax-highlighting/src/lib/state.cpp3
-rw-r--r--src/libs/3rdparty/syntax-highlighting/src/lib/syntaxhighlighter.cpp56
-rw-r--r--src/libs/3rdparty/syntax-highlighting/src/lib/theme.h2
-rw-r--r--src/libs/3rdparty/syntax-highlighting/src/lib/themedata.cpp3
-rw-r--r--src/libs/3rdparty/syntax-highlighting/src/lib/wildcardmatcher.cpp21
-rw-r--r--src/libs/3rdparty/syntax-highlighting/src/lib/wildcardmatcher.h33
-rw-r--r--src/libs/3rdparty/syntax-highlighting/src/lib/worddelimiters.cpp6
-rw-r--r--src/libs/3rdparty/syntax-highlighting/src/lib/worddelimiters_p.h2
-rw-r--r--src/libs/3rdparty/syntax-highlighting/src/lib/xml_p.h2
-rw-r--r--src/libs/3rdparty/syntax-highlighting/syntax-highlighting.pro2
-rw-r--r--src/libs/3rdparty/syntax-highlighting/syntax-highlighting.qbs3
-rw-r--r--src/libs/cplusplus/LookupContext.cpp5
-rw-r--r--src/libs/cplusplus/LookupItem.cpp6
-rw-r--r--src/libs/cplusplus/LookupItem.h3
-rw-r--r--src/libs/extensionsystem/pluginspec.cpp2
-rw-r--r--src/libs/extensionsystem/pluginspec.h4
-rw-r--r--src/libs/languageserverprotocol/jsonrpcmessages.cpp7
-rw-r--r--src/libs/languageserverprotocol/jsonrpcmessages.h9
-rw-r--r--src/libs/languageserverprotocol/lsptypes.cpp10
-rw-r--r--src/libs/languageserverprotocol/lsptypes.h9
-rw-r--r--src/libs/modelinglib/qmt/infrastructure/handle.h2
-rw-r--r--src/libs/modelinglib/qmt/style/defaultstyleengine.cpp15
-rw-r--r--src/libs/modelinglib/qmt/style/objectvisuals.cpp2
-rw-r--r--src/libs/modelinglib/qmt/style/objectvisuals.h4
m---------src/libs/qlitehtml0
-rw-r--r--src/libs/qmldebug/qpacketprotocol.cpp2
-rw-r--r--src/libs/qmljs/qmljscheck.cpp17
-rw-r--r--src/libs/qmljs/qmljsdialect.cpp4
-rw-r--r--src/libs/qmljs/qmljsdialect.h3
-rw-r--r--src/libs/qmljs/qmljsimportdependencies.cpp4
-rw-r--r--src/libs/qmljs/qmljsimportdependencies.h3
-rw-r--r--src/libs/qmljs/qmljsinterpreter.cpp2
-rw-r--r--src/libs/qmljs/qmljsinterpreter.h3
-rw-r--r--src/libs/qmljs/qmljslink.cpp5
-rw-r--r--src/libs/qmljs/qmljsmodelmanagerinterface.cpp4
-rw-r--r--src/libs/tracing/CMakeLists.txt2
-rw-r--r--src/libs/utils/CMakeLists.txt1
-rw-r--r--src/libs/utils/elfreader.cpp2
-rw-r--r--src/libs/utils/filepath.cpp20
-rw-r--r--src/libs/utils/filepath.h21
-rw-r--r--src/libs/utils/fileutils.h13
-rw-r--r--src/libs/utils/id.cpp2
-rw-r--r--src/libs/utils/id.h3
-rw-r--r--src/libs/utils/link.cpp2
-rw-r--r--src/libs/utils/link.h5
-rw-r--r--src/libs/utils/mimetypes/mimeglobpattern.cpp105
-rw-r--r--src/libs/utils/mimetypes/mimeglobpattern_p.h36
-rw-r--r--src/libs/utils/outputformatter.cpp4
-rw-r--r--src/libs/utils/set_algorithm.h18
-rw-r--r--src/libs/utils/threadutils.cpp (renamed from tests/unit/unittest/qmldom-test.cpp)29
-rw-r--r--src/libs/utils/threadutils.h (renamed from src/libs/3rdparty/syntax-highlighting/src/lib/ksyntaxhighlighting_export.h)15
-rw-r--r--src/libs/utils/utils-lib.pri2
-rw-r--r--src/libs/utils/utils.qbs2
-rw-r--r--src/plugins/android/androidconfigurations.cpp79
-rw-r--r--src/plugins/android/androidconfigurations.h10
-rw-r--r--src/plugins/android/androiddeployqtstep.cpp3
-rw-r--r--src/plugins/android/androiddevice.cpp12
-rw-r--r--src/plugins/android/androidqmlpreviewworker.cpp4
-rw-r--r--src/plugins/android/androidrunconfiguration.cpp9
-rw-r--r--src/plugins/android/androidrunnerworker.cpp2
-rw-r--r--src/plugins/android/androidsdkmanager.cpp26
-rw-r--r--src/plugins/android/androidsdkmanagerwidget.cpp11
-rw-r--r--src/plugins/android/androidsdkmodel.cpp47
-rw-r--r--src/plugins/android/androidsdkmodel.h3
-rw-r--r--src/plugins/android/avdmanageroutputparser.cpp3
-rw-r--r--src/plugins/clangcodemodel/clangcodemodelplugin.cpp2
-rw-r--r--src/plugins/clangcodemodel/clangcompletionassistprocessor.cpp37
-rw-r--r--src/plugins/clangcodemodel/clangdclient.cpp277
-rw-r--r--src/plugins/clangcodemodel/clangdiagnostictooltipwidget.cpp24
-rw-r--r--src/plugins/clangcodemodel/clangdiagnostictooltipwidget.h3
-rw-r--r--src/plugins/clangcodemodel/clangeditordocumentprocessor.cpp3
-rw-r--r--src/plugins/clangcodemodel/clangmodelmanagersupport.cpp8
-rw-r--r--src/plugins/clangcodemodel/clangtextmark.cpp4
-rw-r--r--src/plugins/clangcodemodel/clangutils.cpp13
-rw-r--r--src/plugins/clangcodemodel/clangutils.h4
-rw-r--r--src/plugins/clangformat/clangformatfile.cpp2
-rw-r--r--src/plugins/clangtools/clangtoolsdiagnostic.cpp2
-rw-r--r--src/plugins/clangtools/clangtoolsdiagnostic.h4
-rw-r--r--src/plugins/clearcase/clearcaseplugin.cpp8
-rw-r--r--src/plugins/cmakeprojectmanager/cmakebuildsystem.cpp12
-rw-r--r--src/plugins/cmakeprojectmanager/cmakeconfigitem.cpp2
-rw-r--r--src/plugins/cmakeprojectmanager/cmakeconfigitem.h3
-rw-r--r--src/plugins/cmakeprojectmanager/cmakeprocess.cpp12
-rw-r--r--src/plugins/cmakeprojectmanager/fileapidataextractor.cpp75
-rw-r--r--src/plugins/cmakeprojectmanager/fileapidataextractor.h2
-rw-r--r--src/plugins/coreplugin/dialogs/codecselector.cpp2
-rw-r--r--src/plugins/coreplugin/documentmanager.cpp5
-rw-r--r--src/plugins/coreplugin/editormanager/editormanager.cpp2
-rw-r--r--src/plugins/coreplugin/locator/ilocatorfilter.h9
-rw-r--r--src/plugins/coreplugin/locator/locatorsearchutils.cpp25
-rw-r--r--src/plugins/coreplugin/manhattanstyle.cpp13
-rw-r--r--src/plugins/coreplugin/textdocument.cpp8
-rw-r--r--src/plugins/coreplugin/textdocument.h1
-rw-r--r--src/plugins/cppcheck/cppcheckdiagnostic.cpp2
-rw-r--r--src/plugins/cppcheck/cppcheckdiagnostic.h3
-rw-r--r--src/plugins/cppeditor/compileroptionsbuilder.cpp35
-rw-r--r--src/plugins/cppeditor/compileroptionsbuilder.h1
-rw-r--r--src/plugins/cppeditor/cppcodemodelsettings.cpp3
-rw-r--r--src/plugins/cppeditor/cppcodemodelsettingspage.cpp52
-rw-r--r--src/plugins/cppeditor/cppcompletionassist.cpp34
-rw-r--r--src/plugins/cppeditor/cppfollowsymbolundercursor.cpp17
-rw-r--r--src/plugins/cppeditor/cppmodelmanager.cpp4
-rw-r--r--src/plugins/cppeditor/cppprojectfile.cpp14
-rw-r--r--src/plugins/cppeditor/cppprojectfile.h1
-rw-r--r--src/plugins/cppeditor/cppprojectupdater.h2
-rw-r--r--src/plugins/cppeditor/cppquickfixes.cpp2
-rw-r--r--src/plugins/cppeditor/cpptoolsreuse.cpp40
-rw-r--r--src/plugins/cppeditor/cpptoolsreuse.h6
-rw-r--r--src/plugins/cppeditor/semantichighlighter.cpp1
-rw-r--r--src/plugins/debugger/debuggerengine.cpp4
-rw-r--r--src/plugins/debugger/debuggerengine.h2
-rw-r--r--src/plugins/debugger/debuggeritem.cpp2
-rw-r--r--src/plugins/debugger/debuggerruncontrol.cpp2
-rw-r--r--src/plugins/debugger/gdb/gdbengine.cpp8
-rw-r--r--src/plugins/debugger/shared/cdbsymbolpathlisteditor.cpp8
-rw-r--r--src/plugins/debugger/watchhandler.cpp2
-rw-r--r--src/plugins/designer/codemodelhelpers.cpp2
-rw-r--r--src/plugins/designer/formwindowfile.cpp5
-rw-r--r--src/plugins/designer/formwindowfile.h1
-rw-r--r--src/plugins/docker/dockerdevice.cpp24
-rw-r--r--src/plugins/docker/dockerdevice.h1
-rw-r--r--src/plugins/fakevim/fakevimhandler.cpp15
-rw-r--r--src/plugins/fakevim/fakevimplugin.cpp13
-rw-r--r--src/plugins/ios/iosprobe.cpp4
-rw-r--r--src/plugins/ios/iosprobe.h7
-rw-r--r--src/plugins/languageclient/client.cpp9
-rw-r--r--src/plugins/languageclient/client.h3
-rw-r--r--src/plugins/languageclient/languageclientcompletionassist.cpp2
-rw-r--r--src/plugins/modeleditor/modelindexer.cpp5
-rw-r--r--src/plugins/modeleditor/modelindexer.h4
-rw-r--r--src/plugins/perforce/perforceplugin.cpp8
-rw-r--r--src/plugins/projectexplorer/buildtargetinfo.h3
-rw-r--r--src/plugins/projectexplorer/deployablefile.cpp2
-rw-r--r--src/plugins/projectexplorer/deployablefile.h3
-rw-r--r--src/plugins/projectexplorer/devicesupport/devicemanager.cpp12
-rw-r--r--src/plugins/projectexplorer/devicesupport/idevice.cpp5
-rw-r--r--src/plugins/projectexplorer/devicesupport/idevice.h1
-rw-r--r--src/plugins/projectexplorer/expanddata.cpp2
-rw-r--r--src/plugins/projectexplorer/expanddata.h4
-rw-r--r--src/plugins/projectexplorer/gccparser.cpp8
-rw-r--r--src/plugins/projectexplorer/jsonwizard/jsonwizardfactory.cpp162
-rw-r--r--src/plugins/projectexplorer/jsonwizard/jsonwizardfactory.h6
-rw-r--r--src/plugins/projectexplorer/parseissuesdialog.cpp32
-rw-r--r--src/plugins/projectexplorer/project.cpp10
-rw-r--r--src/plugins/projectexplorer/projectexplorer.cpp2
-rw-r--r--src/plugins/projectexplorer/projecttree.cpp4
-rw-r--r--src/plugins/projectexplorer/projecttree.h9
-rw-r--r--src/plugins/projectexplorer/runconfigurationaspects.cpp4
-rw-r--r--src/plugins/projectexplorer/runcontrol.cpp7
-rw-r--r--src/plugins/projectexplorer/task.cpp2
-rw-r--r--src/plugins/projectexplorer/task.h11
-rw-r--r--src/plugins/projectexplorer/treescanner.cpp2
-rw-r--r--src/plugins/qbsprojectmanager/qbsnodetreebuilder.cpp2
-rw-r--r--src/plugins/qmakeprojectmanager/qmakeparsernodes.cpp4
-rw-r--r--src/plugins/qmakeprojectmanager/qmakeparsernodes.h5
-rw-r--r--src/plugins/qmldesigner/CMakeLists.txt2
-rw-r--r--src/plugins/qmldesigner/components/bindingeditor/abstracteditordialog.cpp9
-rw-r--r--src/plugins/qmldesigner/components/bindingeditor/abstracteditordialog.h3
-rw-r--r--src/plugins/qmldesigner/components/bindingeditor/actioneditor.cpp7
-rw-r--r--src/plugins/qmldesigner/components/bindingeditor/actioneditor.h2
-rw-r--r--src/plugins/qmldesigner/components/bindingeditor/bindingeditor.cpp49
-rw-r--r--src/plugins/qmldesigner/components/bindingeditor/bindingeditor.h10
-rw-r--r--src/plugins/qmldesigner/components/bindingeditor/bindingeditorwidget.cpp22
-rw-r--r--src/plugins/qmldesigner/components/componentcore/designeractionmanager.cpp4
-rw-r--r--src/plugins/qmldesigner/components/componentcore/designeractionmanager.h3
-rw-r--r--src/plugins/qmldesigner/components/componentcore/modelnodeoperations.cpp41
-rw-r--r--src/plugins/qmldesigner/components/componentcore/modelnodeoperations.h11
-rw-r--r--src/plugins/qmldesigner/components/connectioneditor/connectionviewwidget.cpp21
-rw-r--r--src/plugins/qmldesigner/components/formeditor/formeditorview.cpp57
-rw-r--r--src/plugins/qmldesigner/components/formeditor/formeditorview.h2
-rw-r--r--src/plugins/qmldesigner/components/integration/designdocument.cpp5
-rw-r--r--src/plugins/qmldesigner/components/itemlibrary/itemlibraryassetimportdialog.cpp5
-rw-r--r--src/plugins/qmldesigner/components/itemlibrary/itemlibrarycategoriesmodel.cpp52
-rw-r--r--src/plugins/qmldesigner/components/itemlibrary/itemlibrarycategoriesmodel.h9
-rw-r--r--src/plugins/qmldesigner/components/itemlibrary/itemlibrarycategory.cpp1
-rw-r--r--src/plugins/qmldesigner/components/itemlibrary/itemlibraryimport.cpp52
-rw-r--r--src/plugins/qmldesigner/components/itemlibrary/itemlibraryimport.h23
-rw-r--r--src/plugins/qmldesigner/components/itemlibrary/itemlibrarymodel.cpp169
-rw-r--r--src/plugins/qmldesigner/components/itemlibrary/itemlibrarymodel.h34
-rw-r--r--src/plugins/qmldesigner/components/itemlibrary/itemlibraryview.cpp8
-rw-r--r--src/plugins/qmldesigner/components/itemlibrary/itemlibrarywidget.cpp83
-rw-r--r--src/plugins/qmldesigner/designercore/include/import.h4
-rw-r--r--src/plugins/qmldesigner/designercore/include/projectstorageids.h2
-rw-r--r--src/plugins/qmldesigner/designercore/include/rewriterview.h2
-rw-r--r--src/plugins/qmldesigner/designercore/metainfo/metainforeader.cpp3
-rw-r--r--src/plugins/qmldesigner/designercore/metainfo/nodemetainfo.cpp2
-rw-r--r--src/plugins/qmldesigner/designercore/model/import.cpp2
-rw-r--r--src/plugins/qmldesigner/designercore/model/qmlobjectnode.cpp2
-rw-r--r--src/plugins/qmldesigner/designercore/model/qmltimelinekeyframegroup.cpp2
-rw-r--r--src/plugins/qmldesigner/designercore/model/rewriterview.cpp33
-rw-r--r--src/plugins/qmldesigner/designercore/projectstorage/projectstorage.h873
-rw-r--r--src/plugins/qmldesigner/designercore/projectstorage/projectstorageexceptions.h6
-rw-r--r--src/plugins/qmldesigner/designercore/projectstorage/projectstorageinterface.h11
-rw-r--r--src/plugins/qmldesigner/designercore/projectstorage/projectstoragetypes.h166
-rw-r--r--src/plugins/qmldesigner/designercore/projectstorage/projectstorageupdater.cpp86
-rw-r--r--src/plugins/qmldesigner/designercore/projectstorage/projectstorageupdater.h24
-rw-r--r--src/plugins/qmldesigner/designercore/projectstorage/qmldocumentparser.cpp197
-rw-r--r--src/plugins/qmldesigner/designercore/projectstorage/qmldocumentparser.h63
-rw-r--r--src/plugins/qmldesigner/designercore/projectstorage/qmltypesparser.cpp307
-rw-r--r--src/plugins/qmldesigner/designercore/projectstorage/qmltypesparser.h63
-rw-r--r--src/plugins/qmldesigner/designercore/projectstorage/qmltypesparserinterface.h2
-rw-r--r--src/plugins/qmldesigner/generatecmakelists.cpp272
-rw-r--r--src/plugins/qmldesigner/generatecmakelists.h45
-rw-r--r--src/plugins/qmldesigner/qmldesignerplugin.cpp3
-rw-r--r--src/plugins/qmldesigner/qmldesignerplugin.pri2
-rw-r--r--src/plugins/qmldesigner/qmldesignerplugin.qbs2
-rw-r--r--src/plugins/qmldesigner/qtquickplugin/images/component-icon.pngbin0 -> 626 bytes
-rw-r--r--src/plugins/qmldesigner/qtquickplugin/images/component-icon16.pngbin0 -> 438 bytes
-rw-r--r--src/plugins/qmldesigner/qtquickplugin/images/component-icon@2x.pngbin0 -> 1107 bytes
-rw-r--r--src/plugins/qmldesigner/qtquickplugin/images/loader-icon.pngbin0 -> 321 bytes
-rw-r--r--src/plugins/qmldesigner/qtquickplugin/images/loader-icon16.pngbin0 -> 222 bytes
-rw-r--r--src/plugins/qmldesigner/qtquickplugin/images/loader-icon@2x.pngbin0 -> 483 bytes
-rw-r--r--src/plugins/qmldesigner/qtquickplugin/images/repeater-icon.pngbin0 -> 191 bytes
-rw-r--r--src/plugins/qmldesigner/qtquickplugin/images/repeater-icon16.pngbin0 -> 187 bytes
-rw-r--r--src/plugins/qmldesigner/qtquickplugin/images/repeater-icon@2x.pngbin0 -> 196 bytes
-rw-r--r--src/plugins/qmldesigner/qtquickplugin/qtquickplugin.qrc9
-rw-r--r--src/plugins/qmldesigner/qtquickplugin/quick.metainfo12
-rw-r--r--src/plugins/qmlpreview/qmldebugtranslationclient.cpp8
-rw-r--r--src/plugins/qmlpreview/qmldebugtranslationclient.h2
-rw-r--r--src/plugins/qmlprofiler/qmlprofilertraceclient.cpp2
-rw-r--r--src/plugins/qmlprojectmanager/fileformat/qmlprojectfileformat.cpp8
-rw-r--r--src/plugins/qmlprojectmanager/fileformat/qmlprojectitem.cpp12
-rw-r--r--src/plugins/qmlprojectmanager/fileformat/qmlprojectitem.h8
-rw-r--r--src/plugins/qmlprojectmanager/qmlmultilanguageaspect.cpp3
-rw-r--r--src/plugins/qmlprojectmanager/qmlproject.cpp18
-rw-r--r--src/plugins/qmlprojectmanager/qmlproject.h2
-rw-r--r--src/plugins/qmlprojectmanager/qmlprojectconstants.h2
-rw-r--r--src/plugins/remotelinux/deploymenttimeinfo.cpp2
-rw-r--r--src/plugins/resourceeditor/resourceeditorplugin.cpp45
-rw-r--r--src/plugins/resourceeditor/resourcenode.cpp16
-rw-r--r--src/plugins/resourceeditor/resourcenode.h1
-rw-r--r--src/plugins/scxmleditor/scxmleditordocument.cpp5
-rw-r--r--src/plugins/scxmleditor/scxmleditordocument.h1
-rw-r--r--src/plugins/studiowelcome/CMakeLists.txt1
-rw-r--r--src/plugins/studiowelcome/studiowelcomeplugin.cpp4
-rw-r--r--src/plugins/texteditor/codeassist/genericproposalmodel.cpp2
-rw-r--r--src/plugins/texteditor/fontsettings.cpp4
-rw-r--r--src/plugins/texteditor/snippets/snippetoverlay.cpp8
-rw-r--r--src/plugins/texteditor/texteditor.cpp4
-rw-r--r--src/plugins/texteditor/texteditor.h3
-rw-r--r--src/plugins/vcsbase/vcsbaseeditor.cpp27
-rw-r--r--src/plugins/webassembly/webassemblyrunconfiguration.cpp39
-rw-r--r--src/shared/proparser/proitems.cpp2
-rw-r--r--src/shared/proparser/proitems.h4
-rw-r--r--src/shared/proparser/qmakeevaluator.cpp2
-rw-r--r--src/shared/proparser/qmakeglobals.h3
m---------src/shared/qbs0
-rw-r--r--src/tools/qml2puppet/CMakeLists.txt1
-rw-r--r--tests/auto/android/CMakeLists.txt3
-rw-r--r--tests/auto/languageserverprotocol/tst_languageserverprotocol.cpp6
-rw-r--r--tests/auto/qml/codemodel/check/equality-checks.qml24
-rw-r--r--tests/manual/docker/Dockerfile-qt-5-ubuntu-20.04-build19
-rw-r--r--tests/unit/unittest/CMakeLists.txt18
-rw-r--r--tests/unit/unittest/gtest-creator-printing.cpp45
-rw-r--r--tests/unit/unittest/gtest-creator-printing.h6
-rw-r--r--tests/unit/unittest/projectstorage-test.cpp4791
-rw-r--r--tests/unit/unittest/projectstoragemock.h15
-rw-r--r--tests/unit/unittest/projectstorageupdater-test.cpp225
-rw-r--r--tests/unit/unittest/qmldocumentparser-test.cpp247
-rw-r--r--tests/unit/unittest/qmltypesparser-test.cpp397
-rw-r--r--tests/unit/unittest/qmltypesparsermock.h2
459 files changed, 9266 insertions, 6121 deletions
diff --git a/.github/workflows/build_cmake.yml b/.github/workflows/build_cmake.yml
index 15cab0d19f..3efc8a7b46 100644
--- a/.github/workflows/build_cmake.yml
+++ b/.github/workflows/build_cmake.yml
@@ -387,17 +387,6 @@ jobs:
message(FATAL_ERROR "Failed to install dependencies")
endif()
endif()
- find_package(Python3 REQUIRED COMPONENTS Interpreter)
- # hack to replace 32-bit python found by this script with 64-bit one
- # required for linking qtcreatorcdbext
- string(REPLACE "x86" "x64" Python3_EXECUTABLE "${Python3_EXECUTABLE}")
- execute_process(
- COMMAND ${Python3_EXECUTABLE} -m pip install --user beautifulsoup4 lxml
- RESULT_VARIABLE result
- )
- if (NOT result EQUAL 0)
- message(FATAL_ERROR "Failed to install python dependencies")
- endif()
- name: Build
shell: cmake -P {0}
@@ -480,6 +469,7 @@ jobs:
--add-config=-DCMAKE_CXX_COMPILER_LAUNCHER=ccache
--add-config=-DIDE_REVISION_URL=https://github.com/$ENV{GITHUB_REPOSITORY}/commits/$ENV{GITHUB_SHA}
--zip-infix=-${{ matrix.config.artifact }}-${{ github.run_id }}
+ --no-qbs
RESULT_VARIABLE result
COMMAND_ECHO STDOUT
OUTPUT_VARIABLE output
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 162b0a9aee..8911572ca0 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -3,6 +3,8 @@ cmake_minimum_required(VERSION 3.10)
## Add paths to check for cmake modules:
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
+option(BUILD_WITH_PCH "Build with precompiled headers" ON)
+
include(FeatureSummary)
include(QtCreatorIDEBranding RESULT_VARIABLE IDE_BRANDING_FILE)
include(QtCreatorTranslations)
@@ -49,8 +51,7 @@ endif()
find_package(Qt5
${IDE_QT_VERSION_MIN}
- COMPONENTS Concurrent Core Gui Network PrintSupport Qml Quick
- QuickWidgets Sql Widgets Xml Core5Compat ${QT_TEST_COMPONENT}
+ COMPONENTS Concurrent Core Gui Network PrintSupport Qml Sql Widgets Xml Core5Compat ${QT_TEST_COMPONENT}
REQUIRED
)
if (Qt5_VERSION VERSION_LESS 6.0.0)
@@ -66,9 +67,7 @@ else()
set(QT_QML_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/qml_modules")
endif()
find_package(Qt5 COMPONENTS LinguistTools QUIET)
-find_package(Qt5 COMPONENTS Designer DesignerComponents Help SerialPort Svg Tools QUIET)
-
-option(BUILD_WITH_PCH "Build with precompiled headers" ON)
+find_package(Qt5 COMPONENTS Quick QuickWidgets Designer DesignerComponents Help SerialPort Svg Tools QUIET)
find_package(Threads)
find_package(Clang QUIET)
diff --git a/doc/qtcreator/config/qtcreator-project.qdocconf b/doc/qtcreator/config/qtcreator-project.qdocconf
index 096548517d..ed35b4e41e 100644
--- a/doc/qtcreator/config/qtcreator-project.qdocconf
+++ b/doc/qtcreator/config/qtcreator-project.qdocconf
@@ -12,11 +12,9 @@ ignorewords += \
MinGW
headerdirs =
-sourcedirs = ../src \
- ../../qtdesignstudio/src/qtquick3d-editor
+sourcedirs = ../src
imagedirs = ../images \
- ../../qtdesignstudio/images \
../../../src/libs/qmleditorwidgets/images \
../../../src/libs/utils/images \
../../../src/plugins/android/images \
@@ -27,14 +25,6 @@ imagedirs = ../images \
../../../src/plugins/diffeditor/images \
../../../src/plugins/help/images \
../../../src/plugins/projectexplorer/images \
- ../../../src/plugins/qmldesigner/components/componentcore/images \
- ../../../src/plugins/qmldesigner/components/edit3d/images \
- ../../../src/plugins/qmldesigner/components/formeditor \
- ../../../src/plugins/qmldesigner/components/navigator \
- ../../../src/plugins/qmldesigner/components/timelineeditor/images \
- ../../../src/plugins/qmldesigner/componentsplugin/images \
- ../../../src/plugins/qmldesigner/qmlpreviewplugin/images \
- ../../../src/plugins/qmldesigner/qtquickplugin/images \
../../../src/plugins/scxmleditor/common/images \
../../../src/plugins/texteditor/images \
../../../src/plugins/valgrind/images \
@@ -50,17 +40,12 @@ depends += qtandroidextras\
qtcmake \
qtcore \
qtqml \
- qtqmlmodels \
qtquick \
qmake \
qtdesigner \
qtdoc \
- qtgraphicaleffects \
qtgui \
qthelp \
- qtquick3d \
- qtquickcontrols \
- qtquickextras \
qtquicktimeline \
qtlinguist \
qtscxml \
diff --git a/doc/qtcreator/images/extraimages/qtcreator-extraimages.qdocconf b/doc/qtcreator/images/extraimages/qtcreator-extraimages.qdocconf
index 9cd8ce979e..af81e51192 100644
--- a/doc/qtcreator/images/extraimages/qtcreator-extraimages.qdocconf
+++ b/doc/qtcreator/images/extraimages/qtcreator-extraimages.qdocconf
@@ -1,12 +1,2 @@
{HTML.extraimages,qhp.QtCreator.extraFiles} += \
- images/commercial.png \
- images/RfEYO-5Mw6s.jpg \
- images/yOUdg1o2KJM.jpg \
- images/DVWd_xMMgvg.jpg \
- images/Ed8WS03C-Vk.jpg \
- images/UfvA04CIXv0.jpg \
- images/FzmLuRHQXaw.jpg \
- images/pEETxSxYazg.jpg \
- images/V3Po15bNErw.jpg \
- images/bMXeeQw6BYs.jpg \
- images/u3kZJjlk3CY.jpg
+ images/commercial.png
diff --git a/doc/qtcreator/images/qml-export-gimp.png b/doc/qtcreator/images/qml-export-gimp.png
deleted file mode 100644
index 5c78a4013b..0000000000
--- a/doc/qtcreator/images/qml-export-gimp.png
+++ /dev/null
Binary files differ
diff --git a/doc/qtcreator/images/qml-observer-context-menu.png b/doc/qtcreator/images/qml-observer-context-menu.png
deleted file mode 100644
index c7d35b0db3..0000000000
--- a/doc/qtcreator/images/qml-observer-context-menu.png
+++ /dev/null
Binary files differ
diff --git a/doc/qtcreator/images/qmldesigner-backends-add.png b/doc/qtcreator/images/qmldesigner-backends-add.png
deleted file mode 100644
index a11ad9923c..0000000000
--- a/doc/qtcreator/images/qmldesigner-backends-add.png
+++ /dev/null
Binary files differ
diff --git a/doc/qtcreator/images/qmldesigner-backends.png b/doc/qtcreator/images/qmldesigner-backends.png
deleted file mode 100644
index f5eb6c26bc..0000000000
--- a/doc/qtcreator/images/qmldesigner-backends.png
+++ /dev/null
Binary files differ
diff --git a/doc/qtcreator/images/qmldesigner-new-project.png b/doc/qtcreator/images/qmldesigner-new-project.png
index 8554f7af89..7bab02c38f 100644
--- a/doc/qtcreator/images/qmldesigner-new-project.png
+++ b/doc/qtcreator/images/qmldesigner-new-project.png
Binary files differ
diff --git a/doc/qtcreator/images/qtcreator-iso-icon-browser.png b/doc/qtcreator/images/qtcreator-iso-icon-browser.png
deleted file mode 100644
index b59b319b1b..0000000000
--- a/doc/qtcreator/images/qtcreator-iso-icon-browser.png
+++ /dev/null
Binary files differ
diff --git a/doc/qtcreator/images/qtcreator-live-preview.png b/doc/qtcreator/images/qtcreator-live-preview.png
index 91d505dce9..4fd62939ab 100644
--- a/doc/qtcreator/images/qtcreator-live-preview.png
+++ b/doc/qtcreator/images/qtcreator-live-preview.png
Binary files differ
diff --git a/doc/qtcreator/images/qtcreator-new-qt-quick-project-wizard.png b/doc/qtcreator/images/qtcreator-new-qt-quick-project-wizard.png
index a2a5bf396f..d9d7509a8a 100644
--- a/doc/qtcreator/images/qtcreator-new-qt-quick-project-wizard.png
+++ b/doc/qtcreator/images/qtcreator-new-qt-quick-project-wizard.png
Binary files differ
diff --git a/doc/qtcreator/images/qtcreator-new-subproject.png b/doc/qtcreator/images/qtcreator-new-subproject.png
index e65a09bee6..7bab02c38f 100644
--- a/doc/qtcreator/images/qtcreator-new-subproject.png
+++ b/doc/qtcreator/images/qtcreator-new-subproject.png
Binary files differ
diff --git a/doc/qtcreator/images/qtcreator-qt-quick-editors.png b/doc/qtcreator/images/qtcreator-qt-quick-editors.png
deleted file mode 100644
index 2d06ea84b4..0000000000
--- a/doc/qtcreator/images/qtcreator-qt-quick-editors.png
+++ /dev/null
Binary files differ
diff --git a/doc/qtcreator/src/debugger/qtquick-debugging.qdoc b/doc/qtcreator/src/debugger/qtquick-debugging.qdoc
index bdc1bda67e..05b89ebab8 100644
--- a/doc/qtcreator/src/debugger/qtquick-debugging.qdoc
+++ b/doc/qtcreator/src/debugger/qtquick-debugging.qdoc
@@ -244,7 +244,12 @@
You can change property values temporarily, without editing the source, and
view the results in the running application. You can change the property
- values permanently in the \uicontrol Properties view in the Design mode.
+ values permanently in
+ \if defined(qtcreator)
+ code.
+ \else
+ the \l Properties view.
+ \endif
\section1 Applying QML Changes at Runtime
diff --git a/doc/qtcreator/src/editors/creator-code-syntax.qdoc b/doc/qtcreator/src/editors/creator-code-syntax.qdoc
index 1afc456647..7ba22031ed 100644
--- a/doc/qtcreator/src/editors/creator-code-syntax.qdoc
+++ b/doc/qtcreator/src/editors/creator-code-syntax.qdoc
@@ -433,45 +433,44 @@
\row
\li M203
\li Warning
- \li Imperative code is not supported in the Design mode
+ \li Imperative code is not supported in \QDS
\li
\row
\li M204
\li Warning
- \li This QML type is not supported in the Design mode
+ \li This QML type is not supported in \QDS
\li
\row
\li M205
\li Warning
- \li Reference to parent QML type cannot be resolved correctly by the
- Design mode
+ \li Reference to parent QML type cannot be resolved correctly by \QDS
\li
\row
\li M206
\li Warning
\li This visual property binding cannot be evaluated in the local
- context and might not show up in Design mode as expected
+ context and might not show up in \QDS as expected
\li
\row
\li M207
\li Warning
- \li Design mode only supports states in the root QML type
+ \li \QDS only supports states in the root QML type
\li
\row
\li M208
\li Error
- \li This id might be ambiguous and is not supported in the Design mode.
+ \li This id might be ambiguous and is not supported in \QDS.
\li
\row
\li M209
\li Error
- \li This type (type name) is not supported as a root element in the
- Design mode.
+ \li This type (type name) is not supported as a root element in
+ \QDS.
\li
\row
@@ -691,8 +690,7 @@
instead of Qt Quick 2}.
You can see the error message when you move the mouse pointer over code that
- \QC underlines in the code editor or when you open a QML file in the Design
- mode.
+ \QC underlines in the code editor or when you open a QML file in \QDS.
To reset the code model, select \uicontrol Tools > \uicontrol {QML/JS} >
\uicontrol {Reset Code Model}.
@@ -700,7 +698,7 @@
\if defined(qtcreator)
If this does not help, try changing the QML emulation layer to the one that
was built with the same Qt version as the one selected in the build and run
- kit. For more information, see \l{Running QML Modules in Design Mode}.
+ kit.
\endif
\section1 Inspecting QML and JavaScript
diff --git a/doc/qtcreator/src/editors/creator-quick-fixes.qdoc b/doc/qtcreator/src/editors/creator-quick-fixes.qdoc
index efe8ecc058..0a063ee3ba 100644
--- a/doc/qtcreator/src/editors/creator-quick-fixes.qdoc
+++ b/doc/qtcreator/src/editors/creator-quick-fixes.qdoc
@@ -869,8 +869,10 @@
\image qtcreator-move-component-into-separate-file.png
- \li QML type name. This action is also available in the
- \uicontrol {Form Editor} in the Design mode.
+ \li QML type name.
+ \if defined(qtdesignstudio)
+ This action is also available in \l {Form Editor}.
+ \endif
\row
\li Split Initializer
\li Reformats a one-line type into a multi-line type. For example,
diff --git a/doc/qtcreator/src/external-resources/external-resources-qds.qdoc b/doc/qtcreator/src/external-resources/external-resources-qds.qdoc
new file mode 100644
index 0000000000..48adc0a98f
--- /dev/null
+++ b/doc/qtcreator/src/external-resources/external-resources-qds.qdoc
@@ -0,0 +1,43 @@
+/****************************************************************************
+**
+** Copyright (C) 2020 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the documentation of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:FDL$
+** 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 Free Documentation License Usage
+** Alternatively, this file may be used under the terms of the GNU Free
+** Documentation License version 1.3 as published by the Free Software
+** Foundation and appearing in the file included in the packaging of
+** this file. Please review the following information to ensure
+** the GNU Free Documentation License version 1.3 requirements
+** will be met: https://www.gnu.org/licenses/fdl-1.3.html.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/*!
+ \externalpage https://doc.qt.io/qtdesignstudio/index.html
+ \title Qt Design Studio Manual
+*/
+/*!
+ \externalpage https://doc.qt.io/qtdesignstudio/studio-optimized-3d-scenes.html
+ \title Creating Optimized 3D Scenes
+*/
+/*!
+ \externalpage https://doc.qt.io/qtdesignstudio/qtquick-optimizing-designs.html
+ \title Optimizing Designs
+*/
+/*!
+ \externalpage https://doc.qt.io/qtdesignstudio/studio-optimized-3d-scenes.html
+ \title Creating Optimized 3D Scenes
+*/
diff --git a/doc/qtcreator/src/external-resources/external-resources.qdoc b/doc/qtcreator/src/external-resources/external-resources.qdoc
index 09c650e3a9..a6ddbe1414 100644
--- a/doc/qtcreator/src/external-resources/external-resources.qdoc
+++ b/doc/qtcreator/src/external-resources/external-resources.qdoc
@@ -101,3 +101,11 @@
\externalpage http://developer.android.com/guide/components/fundamentals.html
\title Android Application Fundamentals
*/
+/*!
+ \externalpage https://doc.qt.io/qt/qtqml-cppintegration-overview.html
+ \title Overview - QML and C++ Integration
+*/
+/*!
+ \externalpage https://doc.qt.io/qt/qtqml-syntax-imports.html#qml-import-path
+ \title QML Import Path
+*/
diff --git a/doc/qtcreator/src/howto/creator-keyboard-shortcuts.qdoc b/doc/qtcreator/src/howto/creator-keyboard-shortcuts.qdoc
index 9d869b6254..56d78ffcd3 100644
--- a/doc/qtcreator/src/howto/creator-keyboard-shortcuts.qdoc
+++ b/doc/qtcreator/src/howto/creator-keyboard-shortcuts.qdoc
@@ -580,10 +580,11 @@
\endtable
\endif
+ \if defined(qtdesignstudio)
\section2 Design Mode Keyboard Shortcuts
You can use the following keyboard shortcuts when editing QML files in the
- Design mode.
+ \uicontrol Design mode.
\table
\header
@@ -603,6 +604,7 @@
\li Toggle right sidebar
\li Ctrl+Alt+Shift+0
\endtable
+ \endif
\section2 Debugging Keyboard Shortcuts
diff --git a/doc/qtcreator/src/howto/creator-only/qtcreator-faq.qdoc b/doc/qtcreator/src/howto/creator-only/qtcreator-faq.qdoc
index 9b1c8bb3b3..9be304d716 100644
--- a/doc/qtcreator/src/howto/creator-only/qtcreator-faq.qdoc
+++ b/doc/qtcreator/src/howto/creator-only/qtcreator-faq.qdoc
@@ -104,7 +104,7 @@
\b {What should I do when \QC complains about missing OpenGL support?}
- Some parts of \QC, such as the Design mode and QML Profiler, use Qt Quick 2, which
+ Some parts of \QC, such as QML Profiler, use Qt Quick 2, which
relies on OpenGL API for drawing. Unfortunately, the use of OpenGL can cause
problems, especially in remote setups and with outdated drivers. In these
cases, \QC displays OpenGL-related error messages on the console or records
diff --git a/doc/qtcreator/src/howto/creator-telemetry.qdoc b/doc/qtcreator/src/howto/creator-telemetry.qdoc
index 746c4b4efb..8ae161c74e 100644
--- a/doc/qtcreator/src/howto/creator-telemetry.qdoc
+++ b/doc/qtcreator/src/howto/creator-telemetry.qdoc
@@ -84,7 +84,7 @@
\page collecting-usage-statistics.html
\previouspage creator-telemetry.html
\if defined(qtdesignstudio)
- \nextpage collecting-user-feedback.html
+ \nextpage studio-user-feedback.html
\else
\nextpage creator-help-overview.html
\endif
@@ -116,67 +116,3 @@
that you do not want to transmit to the backend storage.
\endlist
*/
-
-/*!
- \page collecting-user-feedback.html
- \previouspage collecting-usage-statistics.html
- \nextpage creator-crashpad.html
-
- \title Collecting User Feedback
-
- A pop-up survey asking for your feedback will appear for some of the features
- after you have been using them for some time. You will be asked to to rate
- the usefulness of the feature on a scale of one to five stars. You must rate
- the feature with at least one star if you wish to submit your rating. You
- are also encouraged to give additional written feedback. After you select
- \uicontrol Skip or \uicontrol Submit, the pop-up survey will not appear for
- the same feature again.
-
- \image studio-feedback-popup.png "User feedback pop-up survey for Flow Editor"
-
- For the pop-up survey to appear, you must enable collecting statistics, and
- also allow collecting \uicontrol {4 - Detailed usage statistics} in
- \uicontrol Tools > \uicontrol Options > \uicontrol Telemetry >
- \uicontrol {Usage Statistics} > \uicontrol {Telemetry mode}.
- You can review the submitted user feedback in
- \uicontrol Tools > \uicontrol Options > \uicontrol Telemetry >
- \uicontrol {Usage Statistics} > \uicontrol {Collected Data} by selecting
- \uicontrol {Qt Quick Designer Usage of views and actions} in
- \uicontrol {Data sources}.
-*/
-
-/*!
- \page creator-crashpad.html
- \previouspage collecting-user-feedback.html
- \nextpage studio-packaging.html
-
- \title Reporting Crashes
-
- You can enable \QDS to report crashes automatically. \QDS uses Google
- Crashpad to collect crashes and report them to the Sentry backend storage
- for processing. The purpose of Crashpad is to capture application state in
- sufficient detail to allow developers to diagnose and, where possible, fix
- the issue causing the crash. Crashpad may capture arbitrary contents from
- the memory of a crashed process, including user sensitive information, URLs,
- and other content provided by the users. The collected reports are used for
- the sole purpose of fixing bugs. For more information on Crashpad, see the
- \l {https://chromium.googlesource.com/crashpad/crashpad/+/master/doc/overview_design.md}
- {documentation} by Google. For more information on processing and storing
- of the collected data, see \l {https://sentry.io/security/}
- {Security & Compliance} by Sentry.
-
- To enable sending crash reports, select \uicontrol Tools > \uicontrol
- Options > \uicontrol Environment > \uicontrol System
- (\uicontrol {Qt Design Studio} > \uicontrol Preferences > \uicontrol
- Environment > \uicontrol System on \macos), and then select
- \uicontrol {Enable crash reporting}.
-
- Since crash reports take up disk space, you may wish to remove them when
- they are no longer needed. Select \uicontrol {Clear local crash reports} to
- remove the crash report data.
-
- \image studio-crashpad-checkbox.png "Checkbox for enabling crash reporting"
-
- \note Crashpad is currently only supported on Windows and \macos.
-
-*/
diff --git a/doc/qtcreator/src/overview/creator-only/creator-commercial-overview.qdoc b/doc/qtcreator/src/overview/creator-only/creator-commercial-overview.qdoc
index a227fe0d19..acb4548fb3 100644
--- a/doc/qtcreator/src/overview/creator-only/creator-commercial-overview.qdoc
+++ b/doc/qtcreator/src/overview/creator-only/creator-commercial-overview.qdoc
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2019 The Qt Company Ltd.
+** Copyright (C) 2021 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the Qt Creator documentation.
@@ -40,7 +40,6 @@
\l{http://qt.io/licensing/}{Qt license}:
\list
- \li \l{Browsing ISO 7000 Icons} in the Design mode
\li \l{http://doc.qt.io/QtForDeviceCreation/index.html}{Developing for
embedded devices}
\li \l{http://doc.qt.io/qtcreator/creator-overview-qtasam.html}
diff --git a/doc/qtcreator/src/overview/creator-only/creator-design-overview.qdoc b/doc/qtcreator/src/overview/creator-only/creator-design-overview.qdoc
index 1832facb55..5b530662a6 100644
--- a/doc/qtcreator/src/overview/creator-only/creator-design-overview.qdoc
+++ b/doc/qtcreator/src/overview/creator-only/creator-design-overview.qdoc
@@ -38,16 +38,19 @@
\image front-ui.png
- \QC provides integrated visual editors for designing Qt Quick and
- widget-based applications in the Design mode. The integration
- includes project management and code completion.
+ \QC provides an integrated visual editor designing widget-based applications
+ in the \uicontrol Design mode. The integration includes project management
+ and code completion.
+
+ You can develop Qt Quick applications in the \uicontrol Edit mode or use
+ a separate visual editor, \QDS.
\list
\li \l{Developing Qt Quick Applications}
You can use wizards to create Qt Quick projects containing
- boiler-plate code that you can edit in the Design mode.
+ boiler-plate code that you can edit in the \uicontrol Edit mode.
\li \l{Developing Widget Based Applications}
diff --git a/doc/qtcreator/src/overview/creator-only/creator-issues.qdoc b/doc/qtcreator/src/overview/creator-only/creator-issues.qdoc
index 578a289219..bac658aef5 100644
--- a/doc/qtcreator/src/overview/creator-only/creator-issues.qdoc
+++ b/doc/qtcreator/src/overview/creator-only/creator-issues.qdoc
@@ -143,15 +143,4 @@
{GCC Bugzilla - Bug 44731}.
\endlist
-
- \section1 Design Mode Issues
-
- \list
-
- \li The Design mode uses a QML emulation layer (QML Puppet) to render and preview
- images and to collect data. Executing C++ code might cause the QML
- emulation layer to crash. If it crashes, an error message is displayed and
- you can continue editing the QML file in the code editor.
-
- \endlist
*/
diff --git a/doc/qtcreator/src/overview/creator-only/creator-overview.qdoc b/doc/qtcreator/src/overview/creator-only/creator-overview.qdoc
index 98415f3760..6b4576e077 100644
--- a/doc/qtcreator/src/overview/creator-only/creator-overview.qdoc
+++ b/doc/qtcreator/src/overview/creator-only/creator-overview.qdoc
@@ -64,10 +64,8 @@
\l{Managing Projects}.
\li \b {\l{Designing User Interfaces}}
- \QC provides integrated visual editors for creating Qt Quick and
- widget-based applications in the Design mode.
To create intuitive, modern-looking, fluid user interfaces, you
- can use \l{Qt Quick}.
+ can use \l{Qt Quick} and \QDS.
If you need a traditional user interface that is clearly
structured and enforces a platform look and feel, you can use
the integrated \QD. For more information, see
diff --git a/doc/qtcreator/src/overview/creator-only/creator-tutorials.qdoc b/doc/qtcreator/src/overview/creator-only/creator-tutorials.qdoc
index 912863c18e..698289d48f 100644
--- a/doc/qtcreator/src/overview/creator-only/creator-tutorials.qdoc
+++ b/doc/qtcreator/src/overview/creator-only/creator-tutorials.qdoc
@@ -46,7 +46,7 @@
\li \l{Creating a Qt Quick Application}
- Learn how to use the Design mode to create a Qt Quick application.
+ Learn how to create a Qt Quick application.
\li \l{Creating a Qt Widget Based Application}
diff --git a/doc/qtcreator/src/projects/creator-only/creator-projects-creating.qdoc b/doc/qtcreator/src/projects/creator-only/creator-projects-creating.qdoc
index d997de4a3d..34eeb024b0 100644
--- a/doc/qtcreator/src/projects/creator-only/creator-projects-creating.qdoc
+++ b/doc/qtcreator/src/projects/creator-only/creator-projects-creating.qdoc
@@ -89,7 +89,7 @@
files, as defined by the wizard.
For example, if you choose to create a Qt Quick application, \QC generates a
- QML file that you can modify in the Design mode.
+ QML file that you can modify in the \uicontrol Edit mode.
\section1 Selecting Project Type
@@ -108,7 +108,7 @@
you can deploy, run, and debug on MCU boards. For more
information, see \l {Connecting MCUs}.
\row
- \li {1,2} Application (Qt)
+ \li {1,3} Application (Qt)
\li Qt Widgets Application
\li Uses \QD forms to design a Qt widget based user interface for
the desktop and C++ to implement the application logic.
@@ -116,24 +116,11 @@
\li Qt Console Application
\li Uses a single main.cpp file.
\row
- \li {1,4} Application (Qt Quick)
- \li Qt Quick Application - Empty
+ \li Qt Quick Application
\li Creates a Qt Quick 2 application project that can contain both
QML and C++ code. You can build the application and deploy it
to desktop, embedded, and mobile target platforms.
\row
- \li Qt Quick Application - Scroll
- \li Uses the \l{ScrollView} component to implement a scrollable
- list view (requires Qt 5.9 or later).
- \row
- \li Qt Quick Application - Stack
- \li Uses the \l{StackView} component to implement a set of pages
- with a stack-based navigation model (requires Qt 5.7 or later).
- \row
- \li Qt Quick Application - Swipe
- \li Uses the \l{SwipeView} component to implement a set of pages
- with a swipe-based navigation model (requires Qt 5.7 or later).
- \row
\li {1,4} Application (Qt for Python)
\li Qt for Python - Empty
\li Creates a \l{https://doc.qt.io/qtforpython/index.html}
diff --git a/doc/qtcreator/src/python/creator-python-project.qdocinc b/doc/qtcreator/src/python/creator-python-project.qdocinc
index 7dc7ee6737..7543434e06 100644
--- a/doc/qtcreator/src/python/creator-python-project.qdocinc
+++ b/doc/qtcreator/src/python/creator-python-project.qdocinc
@@ -119,7 +119,8 @@
select \uicontrol {REPL Import File}. To also import all functions from
the file, select \uicontrol {REPL Import *}.
- Open the .ui file in the Design mode to create a widget-based UI in \QD.
+ Open the .ui file in the \uicontrol Design mode to create a widget-based UI
+ in \QD.
The \uicontrol Window wizard adds similar code to the source file, without
the UI bits.
@@ -188,7 +189,8 @@
sys.exit(app.exec_())
\endcode
- Open the .qml file in the Design mode to design a Qt Quick UI in \QMLD.
+ Open the .qml file in the \uicontrol Edit mode to design a Qt Quick UI, or
+ use \QDS.
//! [python qml project wizards]
*/
diff --git a/doc/qtcreator/src/qtcreator-toc.qdoc b/doc/qtcreator/src/qtcreator-toc.qdoc
index e38b0bdea6..c1ce9e2f2f 100644
--- a/doc/qtcreator/src/qtcreator-toc.qdoc
+++ b/doc/qtcreator/src/qtcreator-toc.qdoc
@@ -103,105 +103,9 @@
\li \l{Developing Qt Quick Applications}
\list
\li \l {Creating Qt Quick Projects}
- \li \l {Design Views}
- \list
- \li \l{Form Editor}
- \li \l{3D Editor}
- \li \l{Library}
- \li \l{Navigator}
- \li \l{Properties}
- \li \l{Connection View}
- \li \l{States}
- \li \l{Transition Editor}
- \li \l{Timeline}
- \li \l{Curve Editor}
- \li \l{Text Editor}
- \endlist
- \li \l {Wireframing}
- \list
- \li \l {Components}
- \list
- \li \l {Preset Components}
- \list
- \li \l{Shapes}
- \li \l{Text}
- \li \l{Images}
- \li \l{UI Controls}
- \li \l{User Interaction Methods}
- \li \l{Lists and Other Data Models}
- \li \l{Animations}
- \li \l{3D Views}
- \li \l{Node}
- \li \l{Group}
- \li \l{Instanced Rendering}
- \li \l{Skeletal Animation}
- \li \l{3D Models}
- \li \l{Materials and Shaders}
- \li \l{Textures}
- \li \l{3D Materials}
- \li \l{3D Effects}
- \li \l{Custom Shaders}
- \li \l{Custom Effects and Materials}
- \li \l{Lights}
- \li \l{Cameras}
- \li \l{Scene Environment}
- \li \l{Morph Target}
- \li \l{Repeater3D}
- \li \l{Loader3D}
- \endlist
- \li \l {Creating Component Instances}
- \li \l {Creating Custom Components}
- \list
- \li \l{Creating Buttons}
- \li \l{Creating Scalable Buttons and Borders}
- \endlist
- \endlist
- \li \l{Specifying Component Properties}
- \li \l{Scalable Layouts}
- \li \l{Using Custom Fonts}
- \li \l{Annotating Designs}
- \li \l{UI Files}
- \endlist
- \li \l{Prototyping}
- \list
- \li \l{Creating UI Logic}
- \li \l{Simulating Complex Experiences}
- \list
- \li \l{Loading Placeholder Data}
- \li \l{Using QML Modules with Plugins}
- \endlist
- \li \l {Dynamic Behaviors}
- \list
- \li \l{Adding Connections}
- \list
- \li \l{Connecting Components to Signals}
- \li \l{Adding Bindings Between Properties}
- \li \l{Specifying Dynamic Properties}
- \li \l{Managing C++ Backend Objects}
- \endlist
- \li \l {Adding States}
- \endlist
- \li \l {Exporting 3D Assets}
- \list
- \li \l{Exporting from Blender}{Blender}
- \li \l{Exporting from Maya}{Maya}
- \endlist
- \li \l{Importing 3D Assets}
- \li \l{Exporting Components}
- \endlist
- \li \l{Motion Design}
- \list
- \li \l{Introduction to Animation Techniques}
- \li \l{Creating Timeline Animations}
- \li \l{Editing Easing Curves}
- \li \l{Production Quality}
- \li \l{Optimizing Designs}
- \list
- \li \l{Creating Optimized 3D Scenes}
- \endlist
- \endlist
- \li \l {Browsing ISO 7000 Icons}
\li \l {Converting UI Projects to Applications}
+ \li \l {UI Files}
+ \li \l {Using QML Modules with Plugins}
\endlist
\li \l{Developing Widget Based Applications}
\list
diff --git a/doc/qtcreator/src/qtquick/creator-only/qtquick-app-development.qdoc b/doc/qtcreator/src/qtquick/creator-only/qtquick-app-development.qdoc
index ee038bcd21..3f05a77c06 100644
--- a/doc/qtcreator/src/qtquick/creator-only/qtquick-app-development.qdoc
+++ b/doc/qtcreator/src/qtquick/creator-only/qtquick-app-development.qdoc
@@ -36,63 +36,30 @@
\title Developing Qt Quick Applications
- \list
-
- \li \l {Creating Qt Quick Projects}
-
- You can use wizards to create Qt Quick projects.
-
- \li \l {Design Views}
-
- You can use several different editors and views in the
- Design mode to develop Qt Quick applications.
-
- \li \l {Wireframing}
-
- Plan your UI properly. Know what elements, such as screens,
- components, and states, you need. Create a descriptive wireframe
- and acquire a detailed UI specification before you start to make
- the process of creating the UI more efficient.
-
- \li \l {Prototyping}
+ You can develop Qt Quick applications in the \uicontrol Edit mode or use
+ a separate visual editor, \QDS.
- After your UI wireframe has been approved, you can turn it into
- an interactive prototype to ensure that you and the developers
- share a common vision about the UI appearance and functionality.
+ If you have installed \QDS, and open a .ui.qml or a .qml file in \QC, it
+ asks you whether you would like to open the file in \QDS instead. Select
+ \uicontrol {Open in \QDS} to open the file in \QDS. To continue editing
+ the file in \QC, close the info bar. However, we do not recommend editing
+ \l{UI Files}{UI files} in the \uicontrol Edit mode, because it is easy to
+ add code that is not supported by \QDS. To hide the question, select
+ \uicontrol {Do Not Show Again}.
- \li \l{Motion Design}
+ For more information about using \QDS, see \l{Qt Design Studio Manual}.
- After the wireframing and prototyping phases, you can use the
- supported motion design techniques to fine-tune your UI for
- production. You can use different animation techniques for
- different purposes. \QC supports common motion design techniques,
- such as timeline and keyframe based animation and easing curves,
- as well as screen-to-screen or state-to-state application flows
- and data-driven UI logic animation.
+ For more information about \l{Qt QML}, \l{Qt Quick}, and \l{All QML Types}
+ {QML types}, see the Qt reference documentation available online and
+ in the \uicontrol Help mode.
- \endlist
-
- For more information, watch a video that shows how to perform the tasks
- above:
-
- \youtube pEETxSxYazg
-
- \section1 Related Topics
+ The following topics describe Qt Quick application development using \QC:
\list
- \li \l {Browsing ISO 7000 Icons}
-
- You can add ISO 7000 icons from a library delivered with \QC to
- UIs and change their color.
-
- \li \l {Using QML Modules with Plugins}
+ \li \l {Creating Qt Quick Projects}
- QML modules may use plugins to expose components defined in C++ to
- QML applications. \QC cannot load the plugins to determine the
- details of the contained components, and therefore, the modules must
- provide extra type information for code completion and the semantic
- checks to work correctly.
+ You can use wizards to create Qt Quick projects.
\li \l {Converting UI Projects to Applications}
@@ -101,11 +68,15 @@
convert them to Qt Quick Application projects that contain .pro,
.cpp, and .qrc files.
- \li \l {Exporting Components}
+ \li \l {UI Files}
- \l{UI Files}{UI files} (.ui.qml) can be exported to
- JSON metadata format and PNG assets.
+ If you switch between \QC and \QDS or cooperate with designers on
+ a project, you might encounter .ui.qml files. They are intended to
+ be edited in \QDS only, so you need to be careful not to break the
+ code.
- \endlist
+ \li \l{Using QML Modules with Plugins}
+ You can load C++ plugins for QML to simulate data.
+ \endlist
*/
diff --git a/doc/qtcreator/src/qtquick/creator-only/qtquick-connection-editor-backend.qdoc b/doc/qtcreator/src/qtquick/creator-only/qtquick-connection-editor-backend.qdoc
deleted file mode 100644
index afd9d07e58..0000000000
--- a/doc/qtcreator/src/qtquick/creator-only/qtquick-connection-editor-backend.qdoc
+++ /dev/null
@@ -1,73 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the Qt Creator documentation.
-**
-** 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 Free Documentation License Usage
-** Alternatively, this file may be used under the terms of the GNU Free
-** Documentation License version 1.3 as published by the Free Software
-** Foundation and appearing in the file included in the packaging of
-** this file. Please review the following information to ensure
-** the GNU Free Documentation License version 1.3 requirements
-** will be met: https://www.gnu.org/licenses/fdl-1.3.html.
-**
-****************************************************************************/
-
-/*!
- \previouspage quick-dynamic-properties.html
- \page quick-connections-backend.html
- \nextpage quick-states.html
-
- \title Managing C++ Backend Objects
-
- Many applications provide QObject objects implemented in C++ that work as a
- bridge between QML and C++. Such objects are typically registered with
- \c qmlRegisterType or \c qmlRegisterSingletonType and then used by QML to
- communicate with the C++ backend. Another example of such objects are the
- state machines created by the \l {Using the Qt SCXML Compiler (qscxmlc)}
- {Qt SCXML Compiler}.
-
- Backend objects in a QML file are accessible if the QML file contains the
- required imports. In addition, for a non-singleton QObject, a dynamic
- property that contains the QObject must be specified.
-
- A \e local QObject is instantiated in the current \e .qml file, as follows:
-
- \badcode
- property MyType myType: MyType {}.
- \endcode
-
- Otherwise the property is just defined, as follows:
-
- \badcode
- property MyType myType
- \endcode
-
- To manage backend objects:
-
- \list 1
-
- \li Select \uicontrol {Connection View} > \uicontrol Backends to view
- accessible backend objects.
- \image qmldesigner-backends.png "Connection View, Backends tab"
- \li Select the \inlineimage plus.png
- (\uicontrol Add) button to add a backend object in the
- \uicontrol {Add New C++ Backend} dialog.
- \image qmldesigner-backends-add.png "Add New C++ Backend dialog"
- \li In the \uicontrol Type field, select the backend QObject to add.
- \li Select the \uicontrol {Define object locally} check box if the
- QObject is not registered as a singleton.
- \li Select \uicontrol OK to add the required import and to create the
- property for a non-singleton object.
- \endlist
-*/
diff --git a/doc/qtcreator/src/qtquick/creator-only/qtquick-creating.qdoc b/doc/qtcreator/src/qtquick/creator-only/qtquick-creating.qdoc
index 56c481dd7c..b69f1dc22d 100644
--- a/doc/qtcreator/src/qtquick/creator-only/qtquick-creating.qdoc
+++ b/doc/qtcreator/src/qtquick/creator-only/qtquick-creating.qdoc
@@ -32,7 +32,7 @@
/*!
\previouspage creator-visual-editor.html
\page quick-projects.html
- \nextpage creator-using-qt-quick-designer.html
+ \nextpage quick-converting-ui-projects.html
\title Creating Qt Quick Projects
@@ -47,24 +47,12 @@
\li Wizard Template
\li Purpose
\row
- \li {1,4} Application (Qt Quick)
- \li Qt Quick Application - Empty
+ \li Application (Qt)
+ \li Qt Quick Application
\li Creates a Qt Quick 2 application project that can contain both
QML and C++ code. You can build the application and deploy it
to desktop, embedded, and mobile target platforms.
\row
- \li Qt Quick Application - Scroll
- \li Uses the \l{ScrollView} component to implement a scrollable
- list view (requires Qt 5.9 or later).
- \row
- \li Qt Quick Application - Stack
- \li Uses the \l{StackView} component to implement a set of pages
- with a stack-based navigation model (requires Qt 5.7 or later).
- \row
- \li Qt Quick Application - Swipe
- \li Uses the \l{SwipeView} component to implement a set of pages
- with a swipe-based navigation model (requires Qt 5.7 or later).
- \row
\li Application (Qt for Python)
\li Qt for Python - Qt Quick Application
\li Creates a Python project that contains an empty Qt Quick
@@ -72,14 +60,13 @@
\row
\li Other Project
\li Qt Quick UI Prototype
- \li Creates a \l{Creating Qt Quick UI Projects}{Qt Quick UI project}
- with a single QML file that contains the main view. You can
- preview Qt Quick 2 UI projects in the
- \l{Validating with Target Hardware}{QML Scene preview tool}.
- You do not need to build them, because they do not contain any
- C++ code.
-
- Use this template only if you are prototyping. You cannot create
+ \li Creates a Qt Quick UI project with a single QML file that
+ contains the main view. You can preview Qt Quick 2 UI projects
+ in the QML Scene preview tool. You do not need to build them,
+ because they do not contain any C++ code.
+
+ This project type is compatible with \QDS. However, use this
+ template only if you are prototyping. You cannot create
a full application by using this template.
Qt Quick UI projects cannot be deployed to embedded or mobile
@@ -104,24 +91,17 @@
\list 1
\li Select \uicontrol File > \uicontrol {New File or Project} >
- \uicontrol {Application (Qt Quick)}.
+ \uicontrol {Application (Qt)} > \uicontrol {Qt Quick Application}
+ > \uicontrol Choose.
- \li Select the application type:
- \list
- \li \uicontrol {Qt Quick Application - Empty}
- \li \uicontrol {Qt Quick Application - Scroll}
- \li \uicontrol {Qt Quick Application - Stack}
- \li \uicontrol {Qt Quick Application - Swipe}
- \endlist
-
- \li Select \uicontrol Choose to open the \uicontrol {Project Location}
- dialog.
-
- \li In the \uicontrol Name field, enter a name for the application.
+ \li In the \uicontrol {Project Location} dialog, \uicontrol Name field,
+ enter a name for the project. Keep in mind that you cannot easily
+ change the project name later.
\li In the \uicontrol {Create in} field, enter the path for the project
files. Select the \uicontrol {Use as default project location} check
- box to create new projects in this folder by default.
+ box to create new projects in this folder by default. You can move
+ project folders later without problems.
\li Select \uicontrol Next (or \uicontrol Continue on \macos) to open
the \uicontrol {Define Build System} dialog.
@@ -143,9 +123,8 @@
\note If you have not installed the Qt Virtual Keyboard module when
you installed Qt, an error message will appear when you try to open
- the \e main.qml in the \uicontrol {Form Editor} in the Design mode.
- You can use the \l {Installing Qt}{Qt Maintenance Tool} to install
- Qt Virtual Keyboard.
+ \e main.qml for editing. You can use the \l {Installing Qt}
+ {Qt Maintenance Tool} to install Qt Virtual Keyboard.
\li Select \uicontrol Next to open the \uicontrol {Translation File}
dialog.
@@ -179,14 +158,8 @@
\endlist
- For the Empty and Scroll applications, \QC creates a QML file,
- \e main.qml, that you can modify in the \uicontrol {Form Editor}
- or the \uicontrol {Text Editor}.
-
- For the Stack and Swipe applications, \QC generates two \l{UI Files}{UI files},
- \e Page1Form.ui.qml and \e Page2Form.ui.qml, that you can modify in the
- \uicontrol {Form Editor} and a QML file, \e main.qml, that you can
- modify in the \uicontrol {Text Editor} to add the application logic.
+ \QC creates a QML file, \e main.qml, that you can modify in the
+ \uicontrol Edit mode.
\include creator-python-project.qdocinc python qml project wizards
@@ -240,9 +213,7 @@
\note If you have not installed the Qt Virtual Keyboard module when
you installed Qt, an error message will appear when you try to open
- the \e main.qml in the \uicontrol {Form Editor} in the Design mode.
- You can use the \l {Installing Qt}{Qt Maintenance Tool} to install
- Qt Virtual Keyboard.
+ \e main.qml.
\li Select \uicontrol Next to open the \uicontrol {Kit Selection}
dialog.
diff --git a/doc/qtcreator/src/qtquick/creator-only/qtquick-iso-icon-browser.qdoc b/doc/qtcreator/src/qtquick/creator-only/qtquick-iso-icon-browser.qdoc
deleted file mode 100644
index 48dbe68617..0000000000
--- a/doc/qtcreator/src/qtquick/creator-only/qtquick-iso-icon-browser.qdoc
+++ /dev/null
@@ -1,77 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the Qt Creator documentation.
-**
-** 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 Free Documentation License Usage
-** Alternatively, this file may be used under the terms of the GNU Free
-** Documentation License version 1.3 as published by the Free Software
-** Foundation and appearing in the file included in the packaging of
-** this file. Please review the following information to ensure
-** the GNU Free Documentation License version 1.3 requirements
-** will be met: https://www.gnu.org/licenses/fdl-1.3.html.
-**
-****************************************************************************/
-
-/*!
- \page qtquick-iso-icon-browser.html
- \previouspage studio-3d-scene-environment.html
- \nextpage quick-converting-ui-projects.html
-
- \title Browsing ISO 7000 Icons
-
- \commercial
-
- You can add icons from an ISO 7000 icon library that is installed with \QC
- to Qt Quick applications (commercial only). You can use the
- \uicontrol {ISO Icon Browser} to add a \l {Picture} component and select the
- icon to use for the component. You can change the default color of the icon.
-
- \image qtcreator-iso-icon-browser.png
-
- \section1 Using ISO Icons in Applications
-
- \list 1
-
- \li Create a new Qt Quick Application or open an application in \QC.
-
- \li Open the \l{UI Files}{UI file} (.ui.qml) in \l {Form Editor}.
-
- \li Select \l Library > \uicontrol Components > \inlineimage plus.png
- > \uicontrol {QtQuick.Extras} to import the \l {Qt Quick Extras}
- module.
-
- \li Drag and drop a \uicontrol Picture component from \uicontrol Library
- to \l {Form Editor}.
-
- \li Right-click the picture component and select \uicontrol {Choose Icon}
- to open the \uicontrol {ISO Icon Browser}.
-
- \li To find icons, select a criterion for filtering icons and enter a
- search string.
-
- \li Select an icon in the list, and then select \uicontrol OK to add
- the icon.
-
- \li To view the icon you added, press \key {Ctrl+R} (or \key {Cmd+R})
- to run the application.
-
- \li To adjust the icon color, select the icon on the canvas, and then
- select \uicontrol {Edit Color} in the context menu.
-
- \endlist
-
- \QC generates a Qt resource file called \c iso-icons.qrc that adds the
- icons as a part of your project for delivery with your application.
-
- */
diff --git a/doc/qtcreator/src/qtquick/creator-only/qtquick-tutorial-create-empty-project.qdocinc b/doc/qtcreator/src/qtquick/creator-only/qtquick-tutorial-create-empty-project.qdocinc
index 48ddb0569a..fad9db2bab 100644
--- a/doc/qtcreator/src/qtquick/creator-only/qtquick-tutorial-create-empty-project.qdocinc
+++ b/doc/qtcreator/src/qtquick/creator-only/qtquick-tutorial-create-empty-project.qdocinc
@@ -31,8 +31,7 @@
\list 1
\li Select \uicontrol File > \uicontrol {New File or Project} >
- \uicontrol {Application (Qt Quick)} >
- \uicontrol {Qt Quick Application - Empty}.
+ \uicontrol {Application (Qt)} > \uicontrol {Qt Quick Application}.
\li Select \uicontrol Choose to open the
\uicontrol {Project Location} dialog.
@@ -82,8 +81,8 @@
\endlist
- For more information about the settings that you skipped, see
- \l{Creating Qt Quick Applications}.
+ For more information about the settings that you skipped and the other
+ templates available, see \l{Creating Qt Quick Applications}.
//! [qtquick empty application]
*/
diff --git a/doc/qtcreator/src/qtquick/qtquick-from-qmlproject-to-pro.qdoc b/doc/qtcreator/src/qtquick/qtquick-from-qmlproject-to-pro.qdoc
index 1f3f5c0adc..9a6a39645c 100644
--- a/doc/qtcreator/src/qtquick/qtquick-from-qmlproject-to-pro.qdoc
+++ b/doc/qtcreator/src/qtquick/qtquick-from-qmlproject-to-pro.qdoc
@@ -29,8 +29,8 @@
\previouspage studio-porting-projects.html
\nextpage creator-editor-external.html
\else
- \previouspage qtquick-iso-icon-browser.html
- \nextpage creator-using-qt-designer.html
+ \previouspage quick-projects.html
+ \nextpage creator-quick-ui-forms.html
\endif
\title Converting UI Projects to Applications
@@ -47,8 +47,7 @@
\endlist
For more information about integrating QML and C++, see
- \l{https://doc.qt.io/qt/qtqml-cppintegration-overview.html}
- {Overview - QML and C++ Integration}.
+ \l{Overview - QML and C++ Integration}.
You can use a Qt Creator wizard template to create a Qt Quick application
that is built using the qmake build system and then copy the source files
@@ -61,10 +60,8 @@
compiling them into the binary.
The wizard automatically adds the \c QML_IMPORT_PATH option to the project
- file for specifying the required
- \l{https://doc.qt.io/qt/qtqml-syntax-imports.html#qml-import-path}
- {QML import path}. The path is only needed if more than one subdirectory
- contains QML files.
+ file for specifying the required \l{QML Import Path}{QML import path}. The
+ path is only needed if more than one subdirectory contains QML files.
Then you can use the \l QQuickView class in the main C++ source file to
show the main QML file when the application starts.
@@ -90,8 +87,8 @@
\list 1
\li Select \uicontrol File > \uicontrol {New File or Project} >
- \uicontrol {Application (Qt Quick)} >
- \uicontrol {Qt Quick Application - Empty} > \uicontrol Choose.
+ \uicontrol {Application (Qt)} > \uicontrol {Qt Quick Application} >
+ \uicontrol Choose.
\li In the \uicontrol {Build system} field, select \l qmake as the build
system to use for building and running the project, and then select
\uicontrol Next (or \uicontrol Continue on \macos).
@@ -151,9 +148,13 @@
\section1 Adding Custom Fonts
- To \l{Using Custom Fonts}{use custom fonts} from the Qt Quick UI project,
- call the QFontDatabase::addApplicationFont() function from the \e {main.cpp}
- file.
+ \if defined(qtdesignstudio)
+ To \l{Using Custom Fonts}{use custom fonts}
+ \else
+ To use custom fonts
+ \endif
+ from the Qt Quick UI project, call the QFontDatabase::addApplicationFont()
+ function from the \e {main.cpp} file.
\section1 Adding Qt Quick Designer Components to Qt Installations
diff --git a/doc/qtcreator/src/qtquick/qtquick-live-preview-desktop.qdoc b/doc/qtcreator/src/qtquick/qtquick-live-preview-desktop.qdoc
index a87e833683..5031c56938 100644
--- a/doc/qtcreator/src/qtquick/qtquick-live-preview-desktop.qdoc
+++ b/doc/qtcreator/src/qtquick/qtquick-live-preview-desktop.qdoc
@@ -30,6 +30,12 @@
\title Previewing on Desktop
+ \if defined(qtcreator)
+ To preview the currently active QML file on the desktop, select
+ \uicontrol Build > \uicontrol {QML Preview}.
+
+ \image qtcreator-live-preview.png
+ \else
To preview the currently active QML file on the desktop:
\list
@@ -39,24 +45,21 @@
\li Press \key {Alt+P}.
\endlist
- \if defined(qtcreator)
- \image qtcreator-live-preview.png
- \else
\image studio-live-preview.png
\endif
To preview any QML file that belongs to the project, right-click the project
- name in the \uicontrol Projects view, and select \uicontrol {Preview file}.
+ name in the \l Projects view, and select \uicontrol {Preview File}.
+ \if defined(qtdesignstudio)
To preview the whole UI, select \uicontrol {Show Live Preview}
- when viewing the main QML UI file of the project.
+ when viewing the main QML file of the project.
To view the UI in different sizes, select the zooming level on the toolbar.
The frames-per-second (FPS) refresh rate of animations is displayed in the
\uicontrol FPS field.
- \if defined(qtdesignstudio)
\section1 Selecting the Preview Tool
By default, the QML runtime is used for previewing. To use some
diff --git a/doc/qtcreator/src/qtquick/qtquick-live-preview.qdoc b/doc/qtcreator/src/qtquick/qtquick-live-preview.qdoc
index 42455f4400..47028e00a2 100644
--- a/doc/qtcreator/src/qtquick/qtquick-live-preview.qdoc
+++ b/doc/qtcreator/src/qtquick/qtquick-live-preview.qdoc
@@ -25,7 +25,11 @@
/*!
\page creator-live-preview.html
+ \if defined(qtdesignstudio)
\previouspage quick-states.html
+ \else
+ \previouspage creator-building-running.html
+ \endif
\nextpage creator-live-preview-desktop.html
\title Validating with Target Hardware
@@ -56,8 +60,7 @@
\list
\li \l{Previewing on Desktop}
- You can preview individual QML files or the whole UI in the
- Design mode.
+ You can preview individual QML files or the whole UI.
\li \l{Previewing on Devices}
\if defined(qtcreator)
diff --git a/doc/qtcreator/src/qtquick/qtquick-modules-with-plugins.qdoc b/doc/qtcreator/src/qtquick/qtquick-modules-with-plugins.qdoc
index 31b69054fa..85f7c0135b 100644
--- a/doc/qtcreator/src/qtquick/qtquick-modules-with-plugins.qdoc
+++ b/doc/qtcreator/src/qtquick/qtquick-modules-with-plugins.qdoc
@@ -33,10 +33,11 @@
\page creator-qml-modules-with-plugins.html
\if defined(qtdesignstudio)
\previouspage studio-simulink.html
+ \nextpage qtquick-adding-dynamics.html
\else
- \previouspage qtquick-placeholder-data.html
+ \previouspage creator-quick-ui-forms.html
+ \nextpage creator-using-qt-designer.html
\endif
- \nextpage qtquick-adding-dynamics.html
\title Using QML Modules with Plugins
@@ -45,7 +46,12 @@
the contained components, and therefore, the modules must provide extra type
information for code completion and the semantic checks to work correctly.
- To create a QML module and make it appear in the \l Library view:
+ To create a QML module
+ \if defined(qtdesignstudio)
+ and make it appear in the \l Library view:
+ \else
+ :
+ \endif
\list 1
@@ -69,29 +75,27 @@
\li Create a directory named \c designer in your module directory.
\li Create a \c .metainfo file for your module and place it in the
- \c designer directory. Meta information is needed to display the
+ \c designer directory.
+ \if defined(qtdesignstudio)
+ Meta information is needed to display the
components in the \uicontrol Components tab in \uicontrol Library.
+ \endif
Use a metainfo file delivered with Qt, such as
\c qtquickcontrols2.metainfo, as an example.
\if defined(qtcreator)
\li Import the module into the project, as instructed in
\l {Importing QML Modules}.
-
- \li Make sure that the QML emulation layer used in the Design mode is built with
- the same Qt version as your QML modules. For more information, see
- \l {Running QML Modules in Design Mode}. You can also try
- skipping this step and take it later, if necessary.
+ \endlist
\else
\li Build your module using the same Qt version and compiler as \QDS.
For more information, see \l {Running QML Modules in Design Mode}.
- \endif
-
- \endlist
+ \endlist
Your module should now appear in the \uicontrol Components tab in
\uicontrol Library. Your components should appear in a subsection of
the \uicontrol Components tab if a valid \c .metainfo file is in place.
+ \endif
\if defined(qtcreator)
\section1 Registering QML Types
@@ -105,9 +109,6 @@
complain about unknown types. However, this works only when the source code
is available, and therefore, you must explicitly generate type information
for QML modules with plugins before distributing them.
-
- Classes registered with \c qmlRegisterType() can be used as backend objects
- in the Design mode. For more information, see \l {Adding Connections}.
\endif
\section1 Generating qmltypes Files
@@ -168,26 +169,16 @@
\endcode
The import path affects all the targets built by the CMake project.
- \endif
+ \else
\section1 Running QML Modules in Design Mode
- A QML emulation layer (also called QML Puppet) is used in the Design mode to
- render and preview images and to collect data. To be able to render custom components
- correctly from QML modules, the emulation layer must be built with the same
- Qt version and compiler as the QML modules.
+ A QML emulation layer (also called QML Puppet) is used in the
+ \uicontrol Design mode to render and preview images and to collect
+ data. To be able to render custom components correctly from QML modules,
+ the emulation layer must be built with the same Qt version and compiler
+ as the QML modules.
- \if defined(qtcreator)
- By default, a fallback emulation layer is provided by \QC and built with the same
- Qt version as \QC. Therefore, your QML modules will mostly not work out of
- the box.
-
- To use an emulation layer that is built with the Qt
- configured in the build and run kit for the project, select \uicontrol Tools >
- \uicontrol Options > \uicontrol {Qt Quick} > \uicontrol {Qt Quick Designer} >
- \uicontrol {Use QML emulation layer which is built by the selected Qt} radio button.
- \QC builds the emulation layer when you select the Design mode.
- \else
On Windows, select \uicontrol Help > \uicontrol {About Qt Design Studio} to
check the Qt version and compiler that you need to use to build your plugin.
For example: \c {Based on Qt 5.15.2 (MSVC 2019, 64 bit)}.
@@ -195,21 +186,20 @@
On macOS, select \uicontrol {Qt Design Studio} >
\uicontrol {About Qt Design Studio} to see something like:
\c {Based on Qt 5.15.2 (Clang 10.0 (Apple), 64 bit)}.
- \endif
-
A plugin should behave differently depending on whether it is run by the
emulation layer or an application. For example, animations should not be run
- in the Design mode. You can use the value of the \c QML_PUPPET_MODE
+ in the \uicontrol Design mode. You can use the value of the \c QML_PUPPET_MODE
environment variable to check whether the plugin is currently being run
- by an application or edited in the Design mode.
+ by an application or edited in the \uicontrol Design mode.
- If you want to use a different module in the Design mode than in your actual
- application for example to mockup C++ items, then you can use \c{QML_DESIGNER_IMPORT_PATH}
+ If you want to use a different module in the \uicontrol Design mode
+ than in your actual application for example to mockup C++ items,
+ you can use \c{QML_DESIGNER_IMPORT_PATH}
in the \c{.pro} file (for qmake projects), or declare and set the property
\c qmlDesignerImportPaths in your product (for Qbs projects).
Modules in the import paths defined in \c{QML_DESIGNER_IMPORT_PATH} will be
- used only in the Design mode.
+ used only in the \uicontrol Design mode.
For an example, see \l {Qt Quick Controls - Contact List}.
-
+ \endif
*/
diff --git a/doc/qtcreator/src/qtquick/qtquick-toolbars.qdoc b/doc/qtcreator/src/qtquick/qtquick-toolbars.qdoc
index de00b1e0ed..33c88a9ae3 100644
--- a/doc/qtcreator/src/qtquick/qtquick-toolbars.qdoc
+++ b/doc/qtcreator/src/qtquick/qtquick-toolbars.qdoc
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2018 The Qt Company Ltd.
+** Copyright (C) 2021 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the Qt Creator documentation.
@@ -56,7 +56,13 @@
\section1 Previewing Images
The Qt Quick Toolbar for images allows you to edit the properties of
- \l {Border Image} and \l {Images}{Image} items.
+ \l {Border Image} and
+ \if defined(qtdesignstudio)
+ \l {Images}{Image} items.
+ \else
+ \l Image items.
+ \endif
+
You can scale and tile the images, replace them with other images,
preview them, and change the image margins.
@@ -97,8 +103,12 @@
\section1 Editing Rectangles
The Qt Quick Toolbar for rectangles allows you to edit the properties of
- \l {basic-rectangle}{Rectangle} items. You can change the fill and border
- colors and add gradients.
+ \if defined(qtdesignstudio)
+ \l {basic-rectangle}{Rectangle}
+ \else
+ Rectangle
+ \endif
+ items. You can change the fill and border colors and add gradients.
\image qml-toolbar-rectangle.png "Qt Quick Toolbar for rectangles"
diff --git a/doc/qtcreator/src/qtquick/qtquick-ui-forms.qdoc b/doc/qtcreator/src/qtquick/qtquick-ui-forms.qdoc
index 71fddd3d06..fb76d5250c 100644
--- a/doc/qtcreator/src/qtquick/qtquick-ui-forms.qdoc
+++ b/doc/qtcreator/src/qtquick/qtquick-ui-forms.qdoc
@@ -35,18 +35,24 @@
\previouspage studio-advanced.html
\nextpage creator-telemetry.html
\else
- \previouspage qtquick-annotations.html
- \nextpage qtquick-prototyping.html
+ \previouspage quick-converting-ui-projects.html
+ \nextpage creator-qml-modules-with-plugins.html
\endif
\title UI Files
- You can use \QC wizards to create UI files that have the filename
+ \if defined(qtdesignstudio)
+ You can use \QDS wizards to create UI files that have the filename
extension \e .ui.qml. The UI files can be edited in \l {Form Editor}.
If you use \l {Text Editor} to add code that is not supported
- by \uicontrol {Form Editor}, \QC displays error messages.
+ by \uicontrol {Form Editor}, \QDS displays error messages.
+ \else
+ If you switch between \QC and \QDS or cooperate with designers on
+ a project, you might encounter UI files (.ui.qml). They are intended to
+ be edited in \QDS only.
+ \endif
- The following features are not supported:
+ The following features are not supported in .ui.qml files:
\list
\li JavaScript blocks
@@ -162,6 +168,7 @@
For more information about using the methods, see
\l{https://doc.qt.io/qt/qml-qtqml-qt.html}{Qt QML Methods}.
+ \if defined(qtdesignstudio)
\section1 Using UI Files
You can edit the UI files in the \l {Form Editor} and
@@ -207,5 +214,5 @@
implementation of a component in the .qml file, right-click the
component and select \uicontrol {Go to Implementation} in the
context menu.
-
+ \endif
*/
diff --git a/doc/qtcreator/src/user-interface/creator-file-system-view.qdoc b/doc/qtcreator/src/user-interface/creator-file-system-view.qdoc
index 35792c6b69..630c0a1996 100644
--- a/doc/qtcreator/src/user-interface/creator-file-system-view.qdoc
+++ b/doc/qtcreator/src/user-interface/creator-file-system-view.qdoc
@@ -33,6 +33,7 @@
If you cannot see a file in the \l Projects view, switch to the
\uicontrol {File System} view, which shows all the files in the file system.
+ \if defined(qtdesignstudio)
The following image displays the \uicontrol {File System} view in the
\uicontrol Design mode:
@@ -89,6 +90,7 @@
\endlist
\section1 File System View in Sidebar
+ \endif
In the \uicontrol Edit and \uicontrol Debug mode, the
\uicontrol {File System} view is displayed in the \l{Working with Sidebars}
diff --git a/doc/qtcreator/src/user-interface/creator-open-documents-view.qdoc b/doc/qtcreator/src/user-interface/creator-open-documents-view.qdoc
index 64358b87aa..c64809d8f2 100644
--- a/doc/qtcreator/src/user-interface/creator-open-documents-view.qdoc
+++ b/doc/qtcreator/src/user-interface/creator-open-documents-view.qdoc
@@ -35,8 +35,13 @@
\image qtcreator-open-documents-view.png "Open Documents view"
You can use the context menu to apply some of the functions also available
- in the \uicontrol File menu and in the \l {File System Context Menu}
- {File System} view to the file that is selected in the view.
+ in the \uicontrol File menu
+ \if defined(qtcreator)
+ .
+ \else
+ and in the \l {File System Context Menu} {File System} view to the file
+ that is selected in the view.
+ \endif
In addition, you can:
diff --git a/doc/qtcreator/src/user-interface/creator-projects-view.qdoc b/doc/qtcreator/src/user-interface/creator-projects-view.qdoc
index a9f50806f4..cc9f5cbcfe 100644
--- a/doc/qtcreator/src/user-interface/creator-projects-view.qdoc
+++ b/doc/qtcreator/src/user-interface/creator-projects-view.qdoc
@@ -40,6 +40,7 @@
the build system structure of the project and lists all files that
are part of the project.
+ \if defined(qtdesignstudio)
The following image displays the \uicontrol Projects view in the
\uicontrol Design mode:
@@ -65,14 +66,6 @@
configuration files.
\endlist
- \if defined(qtcreator)
- Files that are not sources or data can be still included into a project's
- distribution tarball by adding their paths to the \c DISTFILES variable in
- the .pro file. This way they also become known to \QC, so that they are
- visible in the \uicontrol Projects view and are known to the locator and
- search.
- \endif
-
\section1 Projects View Context Menu
The \uicontrol Projects view contains context menus for managing projects,
@@ -114,6 +107,7 @@
the \l {File System} view.
\section1 Projects View in Sidebar
+ \endif
In the \uicontrol Edit and \uicontrol Debug mode, the \uicontrol Projects
view is displayed in the \l{Working with Sidebars}{sidebar}. It has a
diff --git a/doc/qtcreator/src/user-interface/creator-ui.qdoc b/doc/qtcreator/src/user-interface/creator-ui.qdoc
index 5bf6d48689..7711dbd01f 100644
--- a/doc/qtcreator/src/user-interface/creator-ui.qdoc
+++ b/doc/qtcreator/src/user-interface/creator-ui.qdoc
@@ -292,11 +292,6 @@
\uicontrol View > \uicontrol {Mode Selector Style} > \uicontrol Hidden.
To only show icons on the mode selector, select the \uicontrol {Icons Only}
style.
-
- The following image displays an example application in \uicontrol Edit mode (1)
- and \uicontrol Design mode (2).
-
- \image qtcreator-qt-quick-editors.png "Edit mode and Design mode"
\endif
You can use \QC in the following modes:
diff --git a/doc/qtcreator/src/user-interface/creator-views.qdoc b/doc/qtcreator/src/user-interface/creator-views.qdoc
index dd45f9411e..65e44a03a9 100644
--- a/doc/qtcreator/src/user-interface/creator-views.qdoc
+++ b/doc/qtcreator/src/user-interface/creator-views.qdoc
@@ -70,10 +70,10 @@
files are included in the current file and which files include
the current file.
\endlist
- \endif
-
+ \else
For more information about views that are only available when editing QML
- files in the Design mode, see \l{Design Views}.
+ files in the \uicontrol Design mode, see \l{Design Views}.
+ \endif
The additional options in a particular view are described in the following
sections.
diff --git a/doc/qtcreator/src/widgets/creator-faq-qtdesigner.qdocinc b/doc/qtcreator/src/widgets/creator-faq-qtdesigner.qdocinc
index f341ce664c..64a607ab05 100644
--- a/doc/qtcreator/src/widgets/creator-faq-qtdesigner.qdocinc
+++ b/doc/qtcreator/src/widgets/creator-faq-qtdesigner.qdocinc
@@ -28,12 +28,12 @@
\section1 Qt Designer Integration Questions
- \b {Why are custom widgets not loaded in Design mode even though it
- works in standalone Qt Designer?}
+ \b {Why are custom widgets not loaded in the \uicontrol Design mode even though
+ it works in standalone \QD?}
- Qt Designer fetches plugins from standard locations and loads the plugins
+ \QD fetches plugins from standard locations and loads the plugins
that match its build key. The locations are different for standalone and
- integrated Qt Designer.
+ integrated \QD.
For more information, see \l{Adding Qt Designer Plugins}.
diff --git a/doc/qtcreator/src/widgets/qtdesigner-overview.qdoc b/doc/qtcreator/src/widgets/qtdesigner-overview.qdoc
index e2342dbe41..42a547d44f 100644
--- a/doc/qtcreator/src/widgets/qtdesigner-overview.qdoc
+++ b/doc/qtcreator/src/widgets/qtdesigner-overview.qdoc
@@ -30,7 +30,7 @@
// **********************************************************************
/*!
- \previouspage creator-exporting-qml.html
+ \previouspage creator-qml-modules-with-plugins.html
\page creator-using-qt-designer.html
\nextpage adding-plugins.html
diff --git a/doc/qtcreator/src/qtquick/qtquick-animation-types.qdoc b/doc/qtdesignstudio/src/components/qtquick-animation-types.qdoc
index f8ffb2918d..f8ffb2918d 100644
--- a/doc/qtcreator/src/qtquick/qtquick-animation-types.qdoc
+++ b/doc/qtdesignstudio/src/components/qtquick-animation-types.qdoc
diff --git a/doc/qtcreator/src/qtquick/qtquick-buttons.qdoc b/doc/qtdesignstudio/src/components/qtquick-buttons.qdoc
index a92328e038..a92328e038 100644
--- a/doc/qtcreator/src/qtquick/qtquick-buttons.qdoc
+++ b/doc/qtdesignstudio/src/components/qtquick-buttons.qdoc
diff --git a/doc/qtcreator/src/qtquick/qtquick-component-context-menu.qdocinc b/doc/qtdesignstudio/src/components/qtquick-component-context-menu.qdocinc
index af83a8e918..af83a8e918 100644
--- a/doc/qtcreator/src/qtquick/qtquick-component-context-menu.qdocinc
+++ b/doc/qtdesignstudio/src/components/qtquick-component-context-menu.qdocinc
diff --git a/doc/qtcreator/src/qtquick/library/qtquick-component-instances.qdoc b/doc/qtdesignstudio/src/components/qtquick-component-instances.qdoc
index eb2e12f8f9..eb2e12f8f9 100644
--- a/doc/qtcreator/src/qtquick/library/qtquick-component-instances.qdoc
+++ b/doc/qtdesignstudio/src/components/qtquick-component-instances.qdoc
diff --git a/doc/qtcreator/src/qtquick/library/qtquick-components-custom.qdoc b/doc/qtdesignstudio/src/components/qtquick-components-custom.qdoc
index dc7ba75268..dc7ba75268 100644
--- a/doc/qtcreator/src/qtquick/library/qtquick-components-custom.qdoc
+++ b/doc/qtdesignstudio/src/components/qtquick-components-custom.qdoc
diff --git a/doc/qtcreator/src/qtquick/qtquick-components.qdoc b/doc/qtdesignstudio/src/components/qtquick-components.qdoc
index d41d4d0bd3..d41d4d0bd3 100644
--- a/doc/qtcreator/src/qtquick/qtquick-components.qdoc
+++ b/doc/qtdesignstudio/src/components/qtquick-components.qdoc
diff --git a/doc/qtcreator/src/qtquick/library/qtquick-controls.qdoc b/doc/qtdesignstudio/src/components/qtquick-controls.qdoc
index a9153f6bcf..a9153f6bcf 100644
--- a/doc/qtcreator/src/qtquick/library/qtquick-controls.qdoc
+++ b/doc/qtdesignstudio/src/components/qtquick-controls.qdoc
diff --git a/doc/qtcreator/src/qtquick/library/qtquick-data-models.qdoc b/doc/qtdesignstudio/src/components/qtquick-data-models.qdoc
index 2f07c78861..2f07c78861 100644
--- a/doc/qtcreator/src/qtquick/library/qtquick-data-models.qdoc
+++ b/doc/qtdesignstudio/src/components/qtquick-data-models.qdoc
diff --git a/doc/qtcreator/src/qtquick/library/qtquick-images.qdoc b/doc/qtdesignstudio/src/components/qtquick-images.qdoc
index 407c2715b5..407c2715b5 100644
--- a/doc/qtcreator/src/qtquick/library/qtquick-images.qdoc
+++ b/doc/qtdesignstudio/src/components/qtquick-images.qdoc
diff --git a/doc/qtcreator/src/qtquick/library/qtquick-pathview-editor.qdocinc b/doc/qtdesignstudio/src/components/qtquick-pathview-editor.qdocinc
index 83bd827f39..83bd827f39 100644
--- a/doc/qtcreator/src/qtquick/library/qtquick-pathview-editor.qdocinc
+++ b/doc/qtdesignstudio/src/components/qtquick-pathview-editor.qdocinc
diff --git a/doc/qtcreator/src/qtquick/qtquick-positioning.qdoc b/doc/qtdesignstudio/src/components/qtquick-positioning.qdoc
index 1076e7a374..1076e7a374 100644
--- a/doc/qtcreator/src/qtquick/qtquick-positioning.qdoc
+++ b/doc/qtdesignstudio/src/components/qtquick-positioning.qdoc
diff --git a/doc/qtcreator/src/qtquick/library/qtquick-preset-components.qdoc b/doc/qtdesignstudio/src/components/qtquick-preset-components.qdoc
index 488dbbdfe0..488dbbdfe0 100644
--- a/doc/qtcreator/src/qtquick/library/qtquick-preset-components.qdoc
+++ b/doc/qtdesignstudio/src/components/qtquick-preset-components.qdoc
diff --git a/doc/qtcreator/src/qtquick/library/qtquick-shapes.qdoc b/doc/qtdesignstudio/src/components/qtquick-shapes.qdoc
index a174a52ab1..a174a52ab1 100644
--- a/doc/qtcreator/src/qtquick/library/qtquick-shapes.qdoc
+++ b/doc/qtdesignstudio/src/components/qtquick-shapes.qdoc
diff --git a/doc/qtcreator/src/qtquick/library/qtquick-text.qdoc b/doc/qtdesignstudio/src/components/qtquick-text.qdoc
index 8202082341..8202082341 100644
--- a/doc/qtcreator/src/qtquick/library/qtquick-text.qdoc
+++ b/doc/qtdesignstudio/src/components/qtquick-text.qdoc
diff --git a/doc/qtcreator/src/qtquick/library/qtquick-user-interaction-methods.qdoc b/doc/qtdesignstudio/src/components/qtquick-user-interaction-methods.qdoc
index 408a5b6a84..408a5b6a84 100644
--- a/doc/qtcreator/src/qtquick/library/qtquick-user-interaction-methods.qdoc
+++ b/doc/qtdesignstudio/src/components/qtquick-user-interaction-methods.qdoc
diff --git a/doc/qtcreator/src/qtquick/qtdesignstudio-simulation-overview.qdoc b/doc/qtdesignstudio/src/overviews/qtdesignstudio-simulation-overview.qdoc
index e5899fe3de..b62198deb8 100644
--- a/doc/qtcreator/src/qtquick/qtdesignstudio-simulation-overview.qdoc
+++ b/doc/qtdesignstudio/src/overviews/qtdesignstudio-simulation-overview.qdoc
@@ -30,14 +30,11 @@
\title Simulating Complex Experiences
-
\QDS enables you to connect UIs to different forms of data from various
sources, such as QML-based data models, JavaScript files, and backend
- services.
- \if definded(qtdesignstudio)
- You can also connect your UI to Simulink to load live data from a
+ services. You can also connect your UI to Simulink to load live data from a
Simulink simulation.
- \endif
+
\list
\li \l{Loading Placeholder Data}
@@ -46,7 +43,6 @@
you can test grid, list, or path views, even though you don't
have access to real data.
- \if defined(qtdesignstudio)
\li \l{Simulating Application Logic}
You can use JavaScript to generate mock data for your UI.
@@ -56,7 +52,6 @@
Use the Simulink connector to connect a Simulink Simulation Model to
your UI. Simulink is a MATLAB-based graphical programming environment
for modeling, simulating, and analyzing multi-domain dynamic systems.
- \endif
\li \l{Using QML Modules with Plugins}
diff --git a/doc/qtcreator/src/qtquick/qtquick-animation-overview.qdoc b/doc/qtdesignstudio/src/overviews/qtquick-animation-overview.qdoc
index 672e62c8ae..672e62c8ae 100644
--- a/doc/qtcreator/src/qtquick/qtquick-animation-overview.qdoc
+++ b/doc/qtdesignstudio/src/overviews/qtquick-animation-overview.qdoc
diff --git a/doc/qtcreator/src/qtquick/qtquick-annotations.qdoc b/doc/qtdesignstudio/src/overviews/qtquick-annotations.qdoc
index 8c493319b9..8c493319b9 100644
--- a/doc/qtcreator/src/qtquick/qtquick-annotations.qdoc
+++ b/doc/qtdesignstudio/src/overviews/qtquick-annotations.qdoc
diff --git a/doc/qtcreator/src/qtquick/qtquick-creating-ui-logic.qdoc b/doc/qtdesignstudio/src/overviews/qtquick-creating-ui-logic.qdoc
index 1b7be83102..1b7be83102 100644
--- a/doc/qtcreator/src/qtquick/qtquick-creating-ui-logic.qdoc
+++ b/doc/qtdesignstudio/src/overviews/qtquick-creating-ui-logic.qdoc
diff --git a/doc/qtcreator/src/qtquick/qtquick-export.qdoc b/doc/qtdesignstudio/src/overviews/qtquick-export.qdoc
index 2aed8fea62..2aed8fea62 100644
--- a/doc/qtcreator/src/qtquick/qtquick-export.qdoc
+++ b/doc/qtdesignstudio/src/overviews/qtquick-export.qdoc
diff --git a/doc/qtcreator/src/qtquick/qtquick-fonts.qdoc b/doc/qtdesignstudio/src/overviews/qtquick-fonts.qdoc
index bf79ffa20b..bf79ffa20b 100644
--- a/doc/qtcreator/src/qtquick/qtquick-fonts.qdoc
+++ b/doc/qtdesignstudio/src/overviews/qtquick-fonts.qdoc
diff --git a/doc/qtcreator/src/qtquick/qtquick-motion-design.qdoc b/doc/qtdesignstudio/src/overviews/qtquick-motion-design.qdoc
index 91f842e08e..91f842e08e 100644
--- a/doc/qtcreator/src/qtquick/qtquick-motion-design.qdoc
+++ b/doc/qtdesignstudio/src/overviews/qtquick-motion-design.qdoc
diff --git a/doc/qtcreator/src/qtquick/qtquick-optimizing-designs.qdoc b/doc/qtdesignstudio/src/overviews/qtquick-optimizing-designs.qdoc
index 0f6c31fe84..0f6c31fe84 100644
--- a/doc/qtcreator/src/qtquick/qtquick-optimizing-designs.qdoc
+++ b/doc/qtdesignstudio/src/overviews/qtquick-optimizing-designs.qdoc
diff --git a/doc/qtcreator/src/qtquick/qtquick-placeholder-data.qdoc b/doc/qtdesignstudio/src/overviews/qtquick-placeholder-data.qdoc
index e684cfda63..237cfc67ef 100644
--- a/doc/qtcreator/src/qtquick/qtquick-placeholder-data.qdoc
+++ b/doc/qtdesignstudio/src/overviews/qtquick-placeholder-data.qdoc
@@ -25,17 +25,12 @@
/*!
\page qtquick-placeholder-data.html
-
\previouspage studio-simulation-overview.html
- \if defined(qtdesignstudio)
\nextpage studio-javascript.html
- \else
- \nextpage creator-qml-modules-with-plugins.html
- \endif
\title Loading Placeholder Data
- \QC supports views, models, and delegates, so that when you add
+ \QDS supports views, models, and delegates, so that when you add
a Grid View, List View, or Path View component, the ListModel and
the delegate component are added automatically.
diff --git a/doc/qtcreator/src/qtquick/qtquick-production-quality-animation.qdoc b/doc/qtdesignstudio/src/overviews/qtquick-production-quality-animation.qdoc
index bfdf435cf6..bfdf435cf6 100644
--- a/doc/qtcreator/src/qtquick/qtquick-production-quality-animation.qdoc
+++ b/doc/qtdesignstudio/src/overviews/qtquick-production-quality-animation.qdoc
diff --git a/doc/qtcreator/src/qtquick/qtquick-prototyping.qdoc b/doc/qtdesignstudio/src/overviews/qtquick-prototyping.qdoc
index 1e9c784000..1e9c784000 100644
--- a/doc/qtcreator/src/qtquick/qtquick-prototyping.qdoc
+++ b/doc/qtdesignstudio/src/overviews/qtquick-prototyping.qdoc
diff --git a/doc/qtcreator/src/qtquick/qtquick-uis.qdoc b/doc/qtdesignstudio/src/overviews/qtquick-uis.qdoc
index 3cb66337fc..3cb66337fc 100644
--- a/doc/qtcreator/src/qtquick/qtquick-uis.qdoc
+++ b/doc/qtdesignstudio/src/overviews/qtquick-uis.qdoc
diff --git a/doc/qtdesignstudio/src/overviews/studio-crashpad.qdoc b/doc/qtdesignstudio/src/overviews/studio-crashpad.qdoc
new file mode 100644
index 0000000000..e195977f8b
--- /dev/null
+++ b/doc/qtdesignstudio/src/overviews/studio-crashpad.qdoc
@@ -0,0 +1,59 @@
+/****************************************************************************
+**
+** Copyright (C) 2021 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt Creator documentation.
+**
+** 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 Free Documentation License Usage
+** Alternatively, this file may be used under the terms of the GNU Free
+** Documentation License version 1.3 as published by the Free Software
+** Foundation and appearing in the file included in the packaging of
+** this file. Please review the following information to ensure
+** the GNU Free Documentation License version 1.3 requirements
+** will be met: https://www.gnu.org/licenses/fdl-1.3.html.
+**
+****************************************************************************/
+
+/*!
+ \page studio-crashpad.html
+ \previouspage studio-user-feedback.html
+ \nextpage studio-packaging.html
+
+ \title Reporting Crashes
+
+ You can enable \QDS to report crashes automatically. \QDS uses Google
+ Crashpad to collect crashes and report them to the Sentry backend storage
+ for processing. The purpose of Crashpad is to capture application state in
+ sufficient detail to allow developers to diagnose and, where possible, fix
+ the issue causing the crash. Crashpad may capture arbitrary contents from
+ the memory of a crashed process, including user sensitive information, URLs,
+ and other content provided by the users. The collected reports are used for
+ the sole purpose of fixing bugs. For more information on Crashpad, see the
+ \l {https://chromium.googlesource.com/crashpad/crashpad/+/master/doc/overview_design.md}
+ {documentation} by Google. For more information on processing and storing
+ of the collected data, see \l {https://sentry.io/security/}
+ {Security & Compliance} by Sentry.
+
+ To enable sending crash reports, select \uicontrol Tools > \uicontrol
+ Options > \uicontrol Environment > \uicontrol System
+ (\uicontrol {Qt Design Studio} > \uicontrol Preferences > \uicontrol
+ Environment > \uicontrol System on \macos), and then select
+ \uicontrol {Enable crash reporting}.
+
+ Since crash reports take up disk space, you may wish to remove them when
+ they are no longer needed. Select \uicontrol {Clear local crash reports} to
+ remove the crash report data.
+
+ \image studio-crashpad-checkbox.png "Checkbox for enabling crash reporting"
+
+ \note Crashpad is currently only supported on Windows and \macos.
+*/
diff --git a/doc/qtdesignstudio/src/overviews/studio-user-feedback.qdoc b/doc/qtdesignstudio/src/overviews/studio-user-feedback.qdoc
new file mode 100644
index 0000000000..463148a1c4
--- /dev/null
+++ b/doc/qtdesignstudio/src/overviews/studio-user-feedback.qdoc
@@ -0,0 +1,52 @@
+/****************************************************************************
+**
+** Copyright (C) 2021 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt Creator documentation.
+**
+** 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 Free Documentation License Usage
+** Alternatively, this file may be used under the terms of the GNU Free
+** Documentation License version 1.3 as published by the Free Software
+** Foundation and appearing in the file included in the packaging of
+** this file. Please review the following information to ensure
+** the GNU Free Documentation License version 1.3 requirements
+** will be met: https://www.gnu.org/licenses/fdl-1.3.html.
+**
+****************************************************************************/
+
+/*!
+ \page studio-user-feedback.html
+ \previouspage collecting-usage-statistics.html
+ \nextpage studio-crashpad.html
+
+ \title Collecting User Feedback
+
+ A pop-up survey asking for your feedback will appear for some of the features
+ after you have been using them for some time. You will be asked to to rate
+ the usefulness of the feature on a scale of one to five stars. You must rate
+ the feature with at least one star if you wish to submit your rating. You
+ are also encouraged to give additional written feedback. After you select
+ \uicontrol Skip or \uicontrol Submit, the pop-up survey will not appear for
+ the same feature again.
+
+ \image studio-feedback-popup.png "User feedback pop-up survey for Flow Editor"
+
+ For the pop-up survey to appear, you must enable collecting statistics, and
+ also allow collecting \uicontrol {4 - Detailed usage statistics} in
+ \uicontrol Tools > \uicontrol Options > \uicontrol Telemetry >
+ \uicontrol {Usage Statistics} > \uicontrol {Telemetry mode}.
+ You can review the submitted user feedback in
+ \uicontrol Tools > \uicontrol Options > \uicontrol Telemetry >
+ \uicontrol {Usage Statistics} > \uicontrol {Collected Data} by selecting
+ \uicontrol {Qt Quick Designer Usage of views and actions} in
+ \uicontrol {Data sources}.
+*/
diff --git a/doc/qtdesignstudio/src/qtbridge/qtbridge-ps-using.qdoc b/doc/qtdesignstudio/src/qtbridge/qtbridge-ps-using.qdoc
index 87a9904cc8..4b45b87670 100644
--- a/doc/qtdesignstudio/src/qtbridge/qtbridge-ps-using.qdoc
+++ b/doc/qtdesignstudio/src/qtbridge/qtbridge-ps-using.qdoc
@@ -127,7 +127,7 @@
\li Second level group layers are merged to their parent.
\li Asset layers are exported as merged.
\li Text layers are always exported as child items.
- \li Images are exported in JPG, PNG, or SVG format, depending on your
+ \li Images are exported in PNG or JPG format, depending on your
selection.
\endlist
diff --git a/doc/qtdesignstudio/src/qtdesignstudio-packaging.qdoc b/doc/qtdesignstudio/src/qtdesignstudio-packaging.qdoc
index d789677057..8f43fca390 100644
--- a/doc/qtdesignstudio/src/qtdesignstudio-packaging.qdoc
+++ b/doc/qtdesignstudio/src/qtdesignstudio-packaging.qdoc
@@ -25,7 +25,7 @@
/*!
\page studio-packaging.html
- \previouspage creator-crashpad.html
+ \previouspage studio-crashpad.html
\nextpage studio-developer-topics.html
\title Packaging Applications
diff --git a/doc/qtcreator/src/qtquick/qtdesignstudio-optimized-3d-scenes.qdoc b/doc/qtdesignstudio/src/qtquick3d-editor/qtdesignstudio-optimized-3d-scenes.qdoc
index 43379fdc35..43379fdc35 100644
--- a/doc/qtcreator/src/qtquick/qtdesignstudio-optimized-3d-scenes.qdoc
+++ b/doc/qtdesignstudio/src/qtquick3d-editor/qtdesignstudio-optimized-3d-scenes.qdoc
diff --git a/doc/qtcreator/src/qtquick/creator-logical-operators.qdocinc b/doc/qtdesignstudio/src/views/creator-logical-operators.qdocinc
index 79284654a4..79284654a4 100644
--- a/doc/qtcreator/src/qtquick/creator-logical-operators.qdocinc
+++ b/doc/qtdesignstudio/src/views/creator-logical-operators.qdocinc
diff --git a/doc/qtcreator/src/qtquick/qtquick-adding-dynamics.qdoc b/doc/qtdesignstudio/src/views/qtquick-adding-dynamics.qdoc
index 274c205c60..274c205c60 100644
--- a/doc/qtcreator/src/qtquick/qtquick-adding-dynamics.qdoc
+++ b/doc/qtdesignstudio/src/views/qtquick-adding-dynamics.qdoc
diff --git a/doc/qtcreator/src/qtquick/qtquick-connection-editor-bindings.qdoc b/doc/qtdesignstudio/src/views/qtquick-connection-editor-bindings.qdoc
index 82107b7507..82107b7507 100644
--- a/doc/qtcreator/src/qtquick/qtquick-connection-editor-bindings.qdoc
+++ b/doc/qtdesignstudio/src/views/qtquick-connection-editor-bindings.qdoc
diff --git a/doc/qtcreator/src/qtquick/qtquick-connection-editor-properties.qdoc b/doc/qtdesignstudio/src/views/qtquick-connection-editor-properties.qdoc
index c0db8d22e7..c0db8d22e7 100644
--- a/doc/qtcreator/src/qtquick/qtquick-connection-editor-properties.qdoc
+++ b/doc/qtdesignstudio/src/views/qtquick-connection-editor-properties.qdoc
diff --git a/doc/qtcreator/src/qtquick/qtquick-connection-editor-signals.qdoc b/doc/qtdesignstudio/src/views/qtquick-connection-editor-signals.qdoc
index 754066a93c..754066a93c 100644
--- a/doc/qtcreator/src/qtquick/qtquick-connection-editor-signals.qdoc
+++ b/doc/qtdesignstudio/src/views/qtquick-connection-editor-signals.qdoc
diff --git a/doc/qtcreator/src/qtquick/qtquick-connection-editor.qdoc b/doc/qtdesignstudio/src/views/qtquick-connection-editor.qdoc
index 62c9bdb543..62c9bdb543 100644
--- a/doc/qtcreator/src/qtquick/qtquick-connection-editor.qdoc
+++ b/doc/qtdesignstudio/src/views/qtquick-connection-editor.qdoc
diff --git a/doc/qtcreator/src/qtquick/qtquick-connection-view.qdoc b/doc/qtdesignstudio/src/views/qtquick-connection-view.qdoc
index 42a74339fb..42a74339fb 100644
--- a/doc/qtcreator/src/qtquick/qtquick-connection-view.qdoc
+++ b/doc/qtdesignstudio/src/views/qtquick-connection-view.qdoc
diff --git a/doc/qtcreator/src/qtquick/qtquick-curve-editor.qdoc b/doc/qtdesignstudio/src/views/qtquick-curve-editor.qdoc
index 7b34c33436..7b34c33436 100644
--- a/doc/qtcreator/src/qtquick/qtquick-curve-editor.qdoc
+++ b/doc/qtdesignstudio/src/views/qtquick-curve-editor.qdoc
diff --git a/doc/qtcreator/src/qtquick/qtquick-designer.qdoc b/doc/qtdesignstudio/src/views/qtquick-designer.qdoc
index 7536e8c757..7536e8c757 100644
--- a/doc/qtcreator/src/qtquick/qtquick-designer.qdoc
+++ b/doc/qtdesignstudio/src/views/qtquick-designer.qdoc
diff --git a/doc/qtcreator/src/qtquick/qtquick-easing-curve-editor.qdoc b/doc/qtdesignstudio/src/views/qtquick-easing-curve-editor.qdoc
index 5a6825ca6c..5a6825ca6c 100644
--- a/doc/qtcreator/src/qtquick/qtquick-easing-curve-editor.qdoc
+++ b/doc/qtdesignstudio/src/views/qtquick-easing-curve-editor.qdoc
diff --git a/doc/qtcreator/src/qtquick/qtquick-form-editor.qdoc b/doc/qtdesignstudio/src/views/qtquick-form-editor.qdoc
index bcd9317615..bcd9317615 100644
--- a/doc/qtcreator/src/qtquick/qtquick-form-editor.qdoc
+++ b/doc/qtdesignstudio/src/views/qtquick-form-editor.qdoc
diff --git a/doc/qtcreator/src/qtquick/qtquick-library.qdoc b/doc/qtdesignstudio/src/views/qtquick-library.qdoc
index b1d03a72e6..b1d03a72e6 100644
--- a/doc/qtcreator/src/qtquick/qtquick-library.qdoc
+++ b/doc/qtdesignstudio/src/views/qtquick-library.qdoc
diff --git a/doc/qtcreator/src/qtquick/qtquick-navigator.qdoc b/doc/qtdesignstudio/src/views/qtquick-navigator.qdoc
index 3e50256a20..3e50256a20 100644
--- a/doc/qtcreator/src/qtquick/qtquick-navigator.qdoc
+++ b/doc/qtdesignstudio/src/views/qtquick-navigator.qdoc
diff --git a/doc/qtcreator/src/qtquick/qtquick-properties-view.qdoc b/doc/qtdesignstudio/src/views/qtquick-properties-view.qdoc
index 9f7fb15820..9f7fb15820 100644
--- a/doc/qtcreator/src/qtquick/qtquick-properties-view.qdoc
+++ b/doc/qtdesignstudio/src/views/qtquick-properties-view.qdoc
diff --git a/doc/qtcreator/src/qtquick/qtquick-properties.qdoc b/doc/qtdesignstudio/src/views/qtquick-properties.qdoc
index 9b7989fb53..9b7989fb53 100644
--- a/doc/qtcreator/src/qtquick/qtquick-properties.qdoc
+++ b/doc/qtdesignstudio/src/views/qtquick-properties.qdoc
diff --git a/doc/qtcreator/src/qtquick/qtquick-states-view.qdoc b/doc/qtdesignstudio/src/views/qtquick-states-view.qdoc
index 66179af77a..66179af77a 100644
--- a/doc/qtcreator/src/qtquick/qtquick-states-view.qdoc
+++ b/doc/qtdesignstudio/src/views/qtquick-states-view.qdoc
diff --git a/doc/qtcreator/src/qtquick/qtquick-states.qdoc b/doc/qtdesignstudio/src/views/qtquick-states.qdoc
index 71d4eba388..71d4eba388 100644
--- a/doc/qtcreator/src/qtquick/qtquick-states.qdoc
+++ b/doc/qtdesignstudio/src/views/qtquick-states.qdoc
diff --git a/doc/qtcreator/src/qtquick/qtquick-text-editor.qdoc b/doc/qtdesignstudio/src/views/qtquick-text-editor.qdoc
index f60821ca9a..f60821ca9a 100644
--- a/doc/qtcreator/src/qtquick/qtquick-text-editor.qdoc
+++ b/doc/qtdesignstudio/src/views/qtquick-text-editor.qdoc
diff --git a/doc/qtcreator/src/qtquick/qtquick-timeline-view.qdoc b/doc/qtdesignstudio/src/views/qtquick-timeline-view.qdoc
index 246442def9..246442def9 100644
--- a/doc/qtcreator/src/qtquick/qtquick-timeline-view.qdoc
+++ b/doc/qtdesignstudio/src/views/qtquick-timeline-view.qdoc
diff --git a/doc/qtcreator/src/qtquick/qtquick-timeline.qdoc b/doc/qtdesignstudio/src/views/qtquick-timeline.qdoc
index ab3e376872..ab3e376872 100644
--- a/doc/qtcreator/src/qtquick/qtquick-timeline.qdoc
+++ b/doc/qtdesignstudio/src/views/qtquick-timeline.qdoc
diff --git a/doc/qtcreator/src/qtquick/qtquick-transition-editor.qdoc b/doc/qtdesignstudio/src/views/qtquick-transition-editor.qdoc
index 12ade5c3c4..12ade5c3c4 100644
--- a/doc/qtcreator/src/qtquick/qtquick-transition-editor.qdoc
+++ b/doc/qtdesignstudio/src/views/qtquick-transition-editor.qdoc
diff --git a/share/qtcreator/qml/qmlpuppet/mockfiles/qt6/AdjustableArrow.qml b/share/qtcreator/qml/qmlpuppet/mockfiles/qt6/AdjustableArrow.qml
index d71b245d33..fe5d3bd5ed 100644
--- a/share/qtcreator/qml/qmlpuppet/mockfiles/qt6/AdjustableArrow.qml
+++ b/share/qtcreator/qml/qmlpuppet/mockfiles/qt6/AdjustableArrow.qml
@@ -31,6 +31,7 @@ DirectionalDraggable {
id: arrowRoot
Model {
+ readonly property bool _edit3dLocked: true // Make this non-pickable
geometry: LineGeometry {
id: lineGeometry
name: "Edit 3D ScalableArrow"
@@ -43,6 +44,7 @@ DirectionalDraggable {
Model {
id: arrowHead
+ readonly property bool _edit3dLocked: true // Make this non-pickable
source: "#Cone"
materials: [ arrowRoot.material ]
y: arrowRoot.length - 3
diff --git a/share/qtcreator/qml/qmlpuppet/mockfiles/qt6/AreaLightHandle.qml b/share/qtcreator/qml/qmlpuppet/mockfiles/qt6/AreaLightHandle.qml
index 78e97e81d4..c2f55bdd43 100644
--- a/share/qtcreator/qml/qmlpuppet/mockfiles/qt6/AreaLightHandle.qml
+++ b/share/qtcreator/qml/qmlpuppet/mockfiles/qt6/AreaLightHandle.qml
@@ -42,6 +42,7 @@ DirectionalDraggable {
Model {
id: handle
+ readonly property bool _edit3dLocked: true // Make this non-pickable
source: "#Sphere"
materials: [ handleRoot.material ]
scale: Qt.vector3d(0.02, 0.02, 0.02)
diff --git a/share/qtcreator/qml/qmlpuppet/mockfiles/qt6/CameraFrustum.qml b/share/qtcreator/qml/qmlpuppet/mockfiles/qt6/CameraFrustum.qml
index adf3d53ab9..2e53ff5d40 100644
--- a/share/qtcreator/qml/qmlpuppet/mockfiles/qt6/CameraFrustum.qml
+++ b/share/qtcreator/qml/qmlpuppet/mockfiles/qt6/CameraFrustum.qml
@@ -35,6 +35,7 @@ Model {
property Node targetNode: null
property Node scene: null
property bool selected: false
+ readonly property bool _edit3dLocked: true // Make this non-pickable
function updateGeometry()
{
diff --git a/share/qtcreator/qml/qmlpuppet/mockfiles/qt6/DirectionalDraggable.qml b/share/qtcreator/qml/qmlpuppet/mockfiles/qt6/DirectionalDraggable.qml
index 5a2f0911dd..2be5344521 100644
--- a/share/qtcreator/qml/qmlpuppet/mockfiles/qt6/DirectionalDraggable.qml
+++ b/share/qtcreator/qml/qmlpuppet/mockfiles/qt6/DirectionalDraggable.qml
@@ -41,6 +41,7 @@ Model {
property real offset: 0
readonly property bool hovering: mouseAreaYZ.hovering || mouseAreaXZ.hovering
+ readonly property bool _edit3dLocked: true // Make this non-pickable
property vector3d _scenePosPressed
property real _posPressed
diff --git a/share/qtcreator/qml/qmlpuppet/mockfiles/qt6/EditView3D.qml b/share/qtcreator/qml/qmlpuppet/mockfiles/qt6/EditView3D.qml
index ebc406c5ad..cd3ec158a4 100644
--- a/share/qtcreator/qml/qmlpuppet/mockfiles/qt6/EditView3D.qml
+++ b/share/qtcreator/qml/qmlpuppet/mockfiles/qt6/EditView3D.qml
@@ -721,6 +721,7 @@ Item {
Model {
id: pivotCap
+ readonly property bool _edit3dLocked: true // Make this non-pickable
source: "#Sphere"
scale: pivotAutoScale.getScale(Qt.vector3d(0.03, 0.03, 0.03))
position: pivotLine.startPos
@@ -760,7 +761,7 @@ Item {
onPressed: (mouse)=> {
if (viewRoot.editView) {
- var pickResult = viewRoot.editView.pick(mouse.x, mouse.y);
+ var pickResult = _generalHelper.pickViewAt(viewRoot.editView, mouse.x, mouse.y);
handleObjectClicked(_generalHelper.resolvePick(pickResult.objectHit),
mouse.modifiers & Qt.ControlModifier);
diff --git a/share/qtcreator/qml/qmlpuppet/mockfiles/qt6/FadeHandle.qml b/share/qtcreator/qml/qmlpuppet/mockfiles/qt6/FadeHandle.qml
index c50406c147..9ad2cd18bb 100644
--- a/share/qtcreator/qml/qmlpuppet/mockfiles/qt6/FadeHandle.qml
+++ b/share/qtcreator/qml/qmlpuppet/mockfiles/qt6/FadeHandle.qml
@@ -41,6 +41,7 @@ DirectionalDraggable {
Model {
id: handle
+ readonly property bool _edit3dLocked: true // Make this non-pickable
source: "#Sphere"
materials: [ handleRoot.material ]
scale: Qt.vector3d(0.02, 0.02, 0.02)
diff --git a/share/qtcreator/qml/qmlpuppet/mockfiles/qt6/HelperGrid.qml b/share/qtcreator/qml/qmlpuppet/mockfiles/qt6/HelperGrid.qml
index b7807d8192..10c7afd65b 100644
--- a/share/qtcreator/qml/qmlpuppet/mockfiles/qt6/HelperGrid.qml
+++ b/share/qtcreator/qml/qmlpuppet/mockfiles/qt6/HelperGrid.qml
@@ -39,6 +39,7 @@ Node {
// Note: Only one instance of HelperGrid is supported, as the geometry names are fixed
Model { // Main grid lines
+ readonly property bool _edit3dLocked: true // Make this non-pickable
geometry: GridGeometry {
id: gridGeometry
name: "3D Edit View Helper Grid"
@@ -55,6 +56,7 @@ Node {
}
Model { // Subdivision lines
+ readonly property bool _edit3dLocked: true // Make this non-pickable
geometry: GridGeometry {
lines: gridGeometry.lines
step: gridGeometry.step
@@ -73,6 +75,7 @@ Node {
}
Model { // Z Axis
+ readonly property bool _edit3dLocked: true // Make this non-pickable
geometry: GridGeometry {
lines: gridGeometry.lines
step: gridGeometry.step
@@ -89,6 +92,7 @@ Node {
]
}
Model { // X Axis
+ readonly property bool _edit3dLocked: true // Make this non-pickable
eulerRotation.z: 90
geometry: GridGeometry {
lines: gridGeometry.lines
diff --git a/share/qtcreator/qml/qmlpuppet/mockfiles/qt6/LightModel.qml b/share/qtcreator/qml/qmlpuppet/mockfiles/qt6/LightModel.qml
index c500f6fbb0..f517f318d2 100644
--- a/share/qtcreator/qml/qmlpuppet/mockfiles/qt6/LightModel.qml
+++ b/share/qtcreator/qml/qmlpuppet/mockfiles/qt6/LightModel.qml
@@ -33,6 +33,7 @@ Model {
property alias geometryName: lightGeometry.name // Name must be unique for each geometry
property alias geometryType: lightGeometry.lightType
property Material material
+ readonly property bool _edit3dLocked: true // Make this non-pickable
function updateGeometry()
{
diff --git a/share/qtcreator/qml/qmlpuppet/mockfiles/qt6/Line3D.qml b/share/qtcreator/qml/qmlpuppet/mockfiles/qt6/Line3D.qml
index 7e034ff75f..f3325bfb34 100644
--- a/share/qtcreator/qml/qmlpuppet/mockfiles/qt6/Line3D.qml
+++ b/share/qtcreator/qml/qmlpuppet/mockfiles/qt6/Line3D.qml
@@ -36,6 +36,7 @@ Node {
property alias color: lineMat.diffuseColor
Model {
+ readonly property bool _edit3dLocked: true // Make this non-pickable
geometry: LineGeometry {
id: lineGeometry
}
diff --git a/share/qtcreator/qml/qmlpuppet/mockfiles/qt6/MaterialNodeView.qml b/share/qtcreator/qml/qmlpuppet/mockfiles/qt6/MaterialNodeView.qml
index 7b5e2a15b2..6103df98c2 100644
--- a/share/qtcreator/qml/qmlpuppet/mockfiles/qt6/MaterialNodeView.qml
+++ b/share/qtcreator/qml/qmlpuppet/mockfiles/qt6/MaterialNodeView.qml
@@ -52,6 +52,7 @@ View3D {
Model {
id: model
+ readonly property bool _edit3dLocked: true // Make this non-pickable
source: "#Sphere"
materials: previewMaterial
}
diff --git a/share/qtcreator/qml/qmlpuppet/mockfiles/qt6/ModelNodeView.qml b/share/qtcreator/qml/qmlpuppet/mockfiles/qt6/ModelNodeView.qml
index 657b0f4c94..7fe6a11416 100644
--- a/share/qtcreator/qml/qmlpuppet/mockfiles/qt6/ModelNodeView.qml
+++ b/share/qtcreator/qml/qmlpuppet/mockfiles/qt6/ModelNodeView.qml
@@ -82,6 +82,7 @@ View3D {
Model {
id: model
+ readonly property bool _edit3dLocked: true // Make this non-pickable
eulerRotation.y: 45
source: sourceModel.source
diff --git a/share/qtcreator/qml/qmlpuppet/mockfiles/qt6/PlanarDraggable.qml b/share/qtcreator/qml/qmlpuppet/mockfiles/qt6/PlanarDraggable.qml
index 1a1fea9f9c..e66d1962a3 100644
--- a/share/qtcreator/qml/qmlpuppet/mockfiles/qt6/PlanarDraggable.qml
+++ b/share/qtcreator/qml/qmlpuppet/mockfiles/qt6/PlanarDraggable.qml
@@ -40,6 +40,7 @@ Model {
property alias mouseArea: mouseArea
readonly property bool hovering: mouseArea.hovering
+ readonly property bool _edit3dLocked: true // Make this non-pickable
property vector3d _scenePosPressed
property vector2d _planePosPressed
diff --git a/share/qtcreator/qml/qmlpuppet/mockfiles/qt6/RotateGizmo.qml b/share/qtcreator/qml/qmlpuppet/mockfiles/qt6/RotateGizmo.qml
index 4998974dab..d77ebc17fb 100644
--- a/share/qtcreator/qml/qmlpuppet/mockfiles/qt6/RotateGizmo.qml
+++ b/share/qtcreator/qml/qmlpuppet/mockfiles/qt6/RotateGizmo.qml
@@ -189,6 +189,7 @@ Node {
Model {
id: freeRotator
+ readonly property bool _edit3dLocked: true // Make this non-pickable
source: "#Sphere"
materials: DefaultMaterial {
id: material
diff --git a/share/qtcreator/qml/qmlpuppet/mockfiles/qt6/RotateRing.qml b/share/qtcreator/qml/qmlpuppet/mockfiles/qt6/RotateRing.qml
index 385806008e..8003839a89 100644
--- a/share/qtcreator/qml/qmlpuppet/mockfiles/qt6/RotateRing.qml
+++ b/share/qtcreator/qml/qmlpuppet/mockfiles/qt6/RotateRing.qml
@@ -45,6 +45,7 @@ Model {
property vector3d _targetPosOnScreen
property vector3d _startRotation
property bool _trackBall
+ readonly property bool _edit3dLocked: true // Make this non-pickable
signal rotateCommit()
signal rotateChange()
diff --git a/share/qtcreator/qml/qmlpuppet/mockfiles/qt6/ScaleGizmo.qml b/share/qtcreator/qml/qmlpuppet/mockfiles/qt6/ScaleGizmo.qml
index e76809f32f..a71001689d 100644
--- a/share/qtcreator/qml/qmlpuppet/mockfiles/qt6/ScaleGizmo.qml
+++ b/share/qtcreator/qml/qmlpuppet/mockfiles/qt6/ScaleGizmo.qml
@@ -166,6 +166,7 @@ Node {
Model {
id: centerCube
+ readonly property bool _edit3dLocked: true // Make this non-pickable
source: "#Cube"
scale: Qt.vector3d(0.024, 0.024, 0.024)
materials: DefaultMaterial {
diff --git a/share/qtcreator/qml/qmlpuppet/mockfiles/qt6/ScaleRod.qml b/share/qtcreator/qml/qmlpuppet/mockfiles/qt6/ScaleRod.qml
index 1857bfddda..9cc5ec0e06 100644
--- a/share/qtcreator/qml/qmlpuppet/mockfiles/qt6/ScaleRod.qml
+++ b/share/qtcreator/qml/qmlpuppet/mockfiles/qt6/ScaleRod.qml
@@ -39,6 +39,7 @@ DirectionalDraggable {
property vector3d _startScale
Model {
+ readonly property bool _edit3dLocked: true // Make this non-pickable
source: "#Cube"
y: 10
scale: Qt.vector3d(0.020, 0.020, 0.020)
diff --git a/share/qtcreator/qml/qmlpuppet/mockfiles/qt6/SelectionBox.qml b/share/qtcreator/qml/qmlpuppet/mockfiles/qt6/SelectionBox.qml
index 1e7cc7b11a..dd3300fd94 100644
--- a/share/qtcreator/qml/qmlpuppet/mockfiles/qt6/SelectionBox.qml
+++ b/share/qtcreator/qml/qmlpuppet/mockfiles/qt6/SelectionBox.qml
@@ -45,6 +45,7 @@ Node {
Model {
id: selectionBoxModel
+ readonly property bool _edit3dLocked: true // Make this non-pickable
geometry: selectionBoxGeometry
scale: selectionBox.targetNode ? selectionBox.targetNode.scale : Qt.vector3d(1, 1, 1)
diff --git a/share/qtcreator/qml/qmlpuppet/mockfiles/qt6/SpotLightHandle.qml b/share/qtcreator/qml/qmlpuppet/mockfiles/qt6/SpotLightHandle.qml
index 1c7322f4e2..314b4166eb 100644
--- a/share/qtcreator/qml/qmlpuppet/mockfiles/qt6/SpotLightHandle.qml
+++ b/share/qtcreator/qml/qmlpuppet/mockfiles/qt6/SpotLightHandle.qml
@@ -41,6 +41,7 @@ DirectionalDraggable {
Model {
id: handle
+ readonly property bool _edit3dLocked: true // Make this non-pickable
source: "#Sphere"
materials: [ handleRoot.material ]
scale: Qt.vector3d(0.02, 0.02, 0.02)
diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/editor3d/generalhelper.cpp b/share/qtcreator/qml/qmlpuppet/qml2puppet/editor3d/generalhelper.cpp
index 02e6f2df59..d3a8b4e8f5 100644
--- a/share/qtcreator/qml/qmlpuppet/qml2puppet/editor3d/generalhelper.cpp
+++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/editor3d/generalhelper.cpp
@@ -267,6 +267,31 @@ void GeneralHelper::delayedPropertySet(QObject *obj, int delay, const QString &p
});
}
+// Returns the first valid QQuick3DPickResult from view at (posX, PosY).
+QQuick3DPickResult GeneralHelper::pickViewAt(QQuick3DViewport *view, float posX, float posY)
+{
+ if (!view)
+ return QQuick3DPickResult();
+
+#if QT_VERSION >= QT_VERSION_CHECK(6, 2, 1)
+ // Make sure global picking is on
+ view->setGlobalPickingEnabled(true);
+
+ // With Qt 6.2+, select first suitable result from all picked objects
+ auto pickResults = view->pickAll(posX, posY);
+ for (auto pickResult : pickResults) {
+ if (isPickable(pickResult.objectHit()))
+ return pickResult;
+ }
+#else
+ // With older Qt version we'll just pick the single object
+ auto pickResult = view->pick(posX, posY);
+ if (isPickable(pickResult.objectHit()))
+ return pickResult;
+#endif
+ return QQuick3DPickResult();
+}
+
QQuick3DNode *GeneralHelper::resolvePick(QQuick3DNode *pickNode)
{
if (pickNode) {
@@ -315,6 +340,10 @@ bool GeneralHelper::isHidden(QQuick3DNode *node)
return false;
}
+bool GeneralHelper::isPickable(QQuick3DNode *node) {
+ return (node && !isLocked(node) && !isHidden(node) && node->visible());
+}
+
void GeneralHelper::storeToolState(const QString &sceneId, const QString &tool, const QVariant &state,
int delay)
{
diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/editor3d/generalhelper.h b/share/qtcreator/qml/qmlpuppet/qml2puppet/editor3d/generalhelper.h
index 6e888980f8..c22f310edd 100644
--- a/share/qtcreator/qml/qmlpuppet/qml2puppet/editor3d/generalhelper.h
+++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/editor3d/generalhelper.h
@@ -35,6 +35,7 @@
#include <QTimer>
#include <QVariant>
#include <QVector3D>
+#include <QtQuick3D/private/qquick3dpickresult_p.h>
QT_BEGIN_NAMESPACE
class QQuick3DCamera;
@@ -74,12 +75,14 @@ public:
Q_INVOKABLE bool fuzzyCompare(double a, double b);
Q_INVOKABLE void delayedPropertySet(QObject *obj, int delay, const QString &property,
const QVariant& value);
+ Q_INVOKABLE QQuick3DPickResult pickViewAt(QQuick3DViewport *view, float posX, float posY);
Q_INVOKABLE QQuick3DNode *resolvePick(QQuick3DNode *pickNode);
Q_INVOKABLE void registerGizmoTarget(QQuick3DNode *node);
Q_INVOKABLE void unregisterGizmoTarget(QQuick3DNode *node);
Q_INVOKABLE bool isLocked(QQuick3DNode *node);
Q_INVOKABLE bool isHidden(QQuick3DNode *node);
+ Q_INVOKABLE bool isPickable(QQuick3DNode *node);
Q_INVOKABLE void storeToolState(const QString &sceneId, const QString &tool,
const QVariant &state, int delayEmit = 0);
diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5informationnodeinstanceserver.cpp b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5informationnodeinstanceserver.cpp
index 19e864e638..ee20e5636c 100644
--- a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5informationnodeinstanceserver.cpp
+++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5informationnodeinstanceserver.cpp
@@ -2047,8 +2047,10 @@ void Qt5InformationNodeInstanceServer::handleInstanceHidden(const ServerNodeInst
// as changes in the node tree (reparenting, adding new nodes) can make the previously set
// hide status based on ancestor unreliable.
node->setProperty("_edit3dHidden", edit3dHidden);
+#if QT_VERSION < QT_VERSION_CHECK(6, 2, 1)
if (auto model = qobject_cast<QQuick3DModel *>(node))
model->setPickable(!edit3dHidden); // allow 3D objects to receive mouse clicks
+#endif
const auto childItems = node->childItems();
for (auto childItem : childItems) {
const ServerNodeInstance quick3dInstance = getQuick3DInstanceAndHidden(childItem);
@@ -2070,7 +2072,9 @@ void Qt5InformationNodeInstanceServer::handleInstanceHidden(const ServerNodeInst
value = QVariant::fromValue(node);
// Specify the actual pick target with dynamic property
checkModel->setProperty("_pickTarget", value);
+#if QT_VERSION < QT_VERSION_CHECK(6, 2, 1)
checkModel->setPickable(!edit3dHidden);
+#endif
}
};
if (auto childNode = qobject_cast<QQuick3DNode *>(childItem))
diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5nodeinstanceserver.cpp b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5nodeinstanceserver.cpp
index 2e1e03fa63..9f8f5caf52 100644
--- a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5nodeinstanceserver.cpp
+++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5nodeinstanceserver.cpp
@@ -37,7 +37,6 @@
#include <addimportcontainer.h>
#include <createscenecommand.h>
#include <reparentinstancescommand.h>
-#include <removeinstancescommand.h>
#include <clearscenecommand.h>
#include <QDebug>
@@ -194,32 +193,6 @@ QList<QQuickItem*> Qt5NodeInstanceServer::allItems() const
return QList<QQuickItem*>();
}
-void Qt5NodeInstanceServer::markRepeaterParentDirty(qint32 id) const
-{
- if (!hasInstanceForId(id))
- return;
-
- ServerNodeInstance instance = instanceForId(id);
- if (!instance.isValid())
- return;
-
- ServerNodeInstance parentInstance = instance.parent();
- if (!parentInstance.isValid())
- return;
-
- // If a Repeater instance was moved/removed, the old parent must be marked dirty to rerender it
- const QByteArray type("QQuickRepeater");
- if (ServerNodeInstance::isSubclassOf(instance.internalObject(), type))
- DesignerSupport::addDirty(parentInstance.rootQuickItem(), QQuickDesignerSupport::Content);
-
- // Repeater's parent must also be dirtied when a child of a repeater was moved/removed.
- if (ServerNodeInstance::isSubclassOf(parentInstance.internalObject(), type)) {
- ServerNodeInstance parentsParent = parentInstance.parent();
- if (parentsParent.isValid())
- DesignerSupport::addDirty(parentsParent.rootQuickItem(), QQuickDesignerSupport::Content);
- }
-}
-
bool Qt5NodeInstanceServer::initRhi(RenderViewData &viewData)
{
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
@@ -550,23 +523,8 @@ void Qt5NodeInstanceServer::clearScene(const ClearSceneCommand &command)
void Qt5NodeInstanceServer::reparentInstances(const ReparentInstancesCommand &command)
{
- const QVector<ReparentContainer> &containerVector = command.reparentInstances();
- for (const ReparentContainer &container : containerVector)
- markRepeaterParentDirty(container.instanceId());
-
NodeInstanceServer::reparentInstances(command.reparentInstances());
startRenderTimer();
}
-void Qt5NodeInstanceServer::removeInstances(const RemoveInstancesCommand &command)
-{
- const QVector<qint32> &idVector = command.instanceIds();
- for (const qint32 id : idVector)
- markRepeaterParentDirty(id);
-
- NodeInstanceServer::removeInstances(command);
- startRenderTimer();
-}
-
-
} // QmlDesigner
diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5nodeinstanceserver.h b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5nodeinstanceserver.h
index d93ecad84e..4af451b61a 100644
--- a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5nodeinstanceserver.h
+++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5nodeinstanceserver.h
@@ -67,7 +67,6 @@ public:
void createScene(const CreateSceneCommand &command) override;
void clearScene(const ClearSceneCommand &command) override;
void reparentInstances(const ReparentInstancesCommand &command) override;
- void removeInstances(const RemoveInstancesCommand &command) override;
QImage grabWindow() override;
QImage grabItem(QQuickItem *item) override;
@@ -80,7 +79,6 @@ protected:
void resetAllItems();
void setupScene(const CreateSceneCommand &command) override;
QList<QQuickItem*> allItems() const;
- void markRepeaterParentDirty(qint32 id) const;
struct RenderViewData {
QPointer<QQuickWindow> window = nullptr;
diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/quickitemnodeinstance.cpp b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/quickitemnodeinstance.cpp
index 1dae931af3..d40d182126 100644
--- a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/quickitemnodeinstance.cpp
+++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/quickitemnodeinstance.cpp
@@ -777,6 +777,8 @@ void QuickItemNodeInstance::reparent(const ObjectNodeInstance::Pointer &oldParen
setMovable(true);
}
+ markRepeaterParentDirty();
+
ObjectNodeInstance::reparent(oldParentInstance, oldParentProperty, newParentInstance, newParentProperty);
if (!newParentInstance)
@@ -841,6 +843,8 @@ void QuickItemNodeInstance::setPropertyVariant(const PropertyName &name, const Q
if (name == "layer.enabled" || name == "layer.effect")
setAllNodesDirtyRecursive(quickItem());
+ markRepeaterParentDirty();
+
ObjectNodeInstance::setPropertyVariant(name, value);
refresh();
@@ -860,6 +864,8 @@ void QuickItemNodeInstance::setPropertyBinding(const PropertyName &name, const Q
if (name.startsWith("anchors.") && isRootNodeInstance())
return;
+ markRepeaterParentDirty();
+
ObjectNodeInstance::setPropertyBinding(name, expression);
refresh();
@@ -937,6 +943,8 @@ void QuickItemNodeInstance::resetProperty(const PropertyName &name)
resetVertical();
}
+ markRepeaterParentDirty();
+
ObjectNodeInstance::resetProperty(name);
if (isInLayoutable())
@@ -1013,6 +1021,35 @@ QQuickItem *QuickItemNodeInstance::quickItem() const
return static_cast<QQuickItem*>(object());
}
+void QuickItemNodeInstance::markRepeaterParentDirty() const
+{
+ const qint32 id = instanceId();
+ if (id <= 0 && !isValid())
+ return;
+
+ QQuickItem *item = quickItem();
+ if (!item)
+ return;
+
+ QQuickItem *parentItem = item->parentItem();
+ if (!parentItem)
+ return;
+
+ // If a Repeater instance was changed in any way, the parent must be marked dirty to rerender it
+ const QByteArray type("QQuickRepeater");
+ if (ServerNodeInstance::isSubclassOf(item, type))
+ DesignerSupport::addDirty(parentItem, QQuickDesignerSupport::Content);
+
+ // Repeater's parent must also be dirtied when a child of a repeater was changed
+ if (ServerNodeInstance::isSubclassOf(parentItem, type)) {
+ QQuickItem *parentsParent = parentItem->parentItem();
+ if (parentsParent)
+ DesignerSupport::addDirty(parentsParent, QQuickDesignerSupport::Content);
+ }
+}
+
+
+
} // namespace Internal
} // namespace QmlDesigner
diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/quickitemnodeinstance.h b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/quickitemnodeinstance.h
index 77d3a3fc6b..46b22b8c9a 100644
--- a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/quickitemnodeinstance.h
+++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/quickitemnodeinstance.h
@@ -130,6 +130,7 @@ protected:
double x() const;
double y() const;
bool checkIfRefFromEffect(qint32 id);
+ void markRepeaterParentDirty() const;
private: //variables
QPointer<QQuickItem> m_contentItem;
diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/servernodeinstance.cpp b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/servernodeinstance.cpp
index 2aa17d9e2b..97b5031260 100644
--- a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/servernodeinstance.cpp
+++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/servernodeinstance.cpp
@@ -234,6 +234,25 @@ bool isInPathList(const QStringList &pathList, const QString &componentPath)
});
}
+bool canBeCreatedAsPrimitive(const QStringList &pathList,
+ const InstanceContainer &instanceContainer,
+ QQmlContext *context,
+ QObject *&object)
+{
+ if (isInPathList(pathList, instanceContainer.componentPath())) {
+ object = Internal::ObjectNodeInstance::createPrimitive(QString::fromUtf8(
+ instanceContainer.type()),
+ instanceContainer.majorNumber(),
+ instanceContainer.minorNumber(),
+ context);
+
+ if (object)
+ return true;
+
+ }
+ return false;
+}
+
ServerNodeInstance ServerNodeInstance::create(NodeInstanceServer *nodeInstanceServer,
const InstanceContainer &instanceContainer,
ComponentWrap componentWrap)
@@ -249,8 +268,8 @@ ServerNodeInstance ServerNodeInstance::create(NodeInstanceServer *nodeInstanceSe
if (object == nullptr)
nodeInstanceServer->sendDebugOutput(DebugOutputCommand::ErrorType, QLatin1String("Custom parser object could not be created."), instanceContainer.instanceId());
} else if (!instanceContainer.componentPath().isEmpty()
- && !isInPathList(nodeInstanceServer->engine()->importPathList(),
- instanceContainer.componentPath())) {
+ && !canBeCreatedAsPrimitive(nodeInstanceServer->engine()->importPathList(),
+ instanceContainer, nodeInstanceServer->context(), object)) {
object = Internal::ObjectNodeInstance::createComponent(instanceContainer.componentPath(), nodeInstanceServer->context());
if (object == nullptr) {
object = Internal::ObjectNodeInstance::createPrimitive(QString::fromUtf8(instanceContainer.type()), instanceContainer.majorNumber(), instanceContainer.minorNumber(), nodeInstanceServer->context());
@@ -260,7 +279,7 @@ ServerNodeInstance ServerNodeInstance::create(NodeInstanceServer *nodeInstanceSe
nodeInstanceServer->sendDebugOutput(DebugOutputCommand::ErrorType, message + errors, instanceContainer.instanceId());
}
}
- } else {
+ } else if (!object) {
object = Internal::ObjectNodeInstance::createPrimitive(QString::fromUtf8(instanceContainer.type()), instanceContainer.majorNumber(), instanceContainer.minorNumber(), nodeInstanceServer->context());
if (object == nullptr)
nodeInstanceServer->sendDebugOutput(DebugOutputCommand::ErrorType, QLatin1String("Item could not be created."), instanceContainer.instanceId());
@@ -498,7 +517,7 @@ QDebug operator <<(QDebug debug, const ServerNodeInstance &instance)
return debug.space();
}
-uint qHash(const ServerNodeInstance &instance)
+ServerNodeInstance::QHashValueType qHash(const ServerNodeInstance &instance)
{
return ::qHash(instance.instanceId());
}
diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/servernodeinstance.h b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/servernodeinstance.h
index 52ead77e12..7fd6453daa 100644
--- a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/servernodeinstance.h
+++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/servernodeinstance.h
@@ -67,6 +67,13 @@ namespace Internal {
class ServerNodeInstance
{
+public:
+#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
+using QHashValueType = uint;
+#else
+using QHashValueType = size_t;
+#endif
+
friend class NodeInstanceServer;
friend class Qt4NodeInstanceServer;
friend class Qt4PreviewNodeInstanceServer;
@@ -76,7 +83,7 @@ class ServerNodeInstance
friend class Qt5CapturePreviewNodeInstanceServer;
friend class Qt5TestNodeInstanceServer;
friend class QHash<qint32, ServerNodeInstance>;
- friend uint qHash(const ServerNodeInstance &instance);
+ friend QHashValueType qHash(const ServerNodeInstance &instance);
friend bool operator==(const ServerNodeInstance &first, const ServerNodeInstance &second);
friend QDebug operator<<(QDebug debug, const ServerNodeInstance &instance);
friend class NodeMetaInfo;
@@ -220,7 +227,7 @@ private: // variables
QSharedPointer<Internal::ObjectNodeInstance> m_nodeInstance;
};
-uint qHash(const ServerNodeInstance &instance);
+ServerNodeInstance::QHashValueType qHash(const ServerNodeInstance &instance);
bool operator ==(const ServerNodeInstance &first, const ServerNodeInstance &second);
bool operator <(const ServerNodeInstance &first, const ServerNodeInstance &second);
QDebug operator <<(QDebug debug, const ServerNodeInstance &instance);
diff --git a/share/qtcreator/qmldesigner/itemLibraryQmlSources/ItemsView.qml b/share/qtcreator/qmldesigner/itemLibraryQmlSources/ItemsView.qml
index de9d50f042..815d4427ad 100644
--- a/share/qtcreator/qmldesigner/itemLibraryQmlSources/ItemsView.qml
+++ b/share/qtcreator/qmldesigner/itemLibraryQmlSources/ItemsView.qml
@@ -78,15 +78,10 @@ Item {
property string importToRemove: ""
property string importToAdd: ""
- property var currentItem: null
property var currentCategory: null
property var currentImport: null
property bool isHorizontalView: false
- // horizontal component lib variables
- property var selectedCategory: null
- property var selectedCategoryImport: null
-
// called from C++ to close context menu on focus out
function closeContextMenu()
{
@@ -94,21 +89,6 @@ Item {
itemContextMenu.close()
}
- function showImportCategories()
- {
- if (itemLibraryModel.isAllCategoriesHidden()) {
- itemsView.currentImport.importCatVisibleState = true
- if (!itemLibraryModel.getIsAnyCategoryHidden())
- itemLibraryModel.isAnyCategoryHidden = false
-
- itemsView.selectedCategory = itemLibraryModel.selectImportFirstVisibleCategory()
- }
-
- itemsView.currentImport.importCatVisibleState = true
- if (!itemLibraryModel.getIsAnyCategoryHidden())
- itemLibraryModel.isAnyCategoryHidden = false
- }
-
onWidthChanged: {
itemsView.isHorizontalView = itemsView.width > widthLimit
}
@@ -135,10 +115,7 @@ Item {
visible: itemsView.currentCategory === null
height: visible ? implicitHeight : 0
enabled: itemsView.importToRemove !== ""
- onTriggered: {
- showImportCategories()
- rootView.removeImport(itemsView.importToRemove)
- }
+ onTriggered: rootView.removeImport(itemsView.importToRemove)
}
StudioControls.MenuSeparator {
@@ -169,12 +146,8 @@ Item {
text: qsTr("Hide Category")
visible: itemsView.currentCategory
height: visible ? implicitHeight : 0
- onTriggered: {
- itemLibraryModel.isAnyCategoryHidden = true
- itemsView.currentCategory.categoryVisible = false
- itemsView.currentCategory.categorySelected = false
- itemsView.selectedCategory = itemLibraryModel.selectImportFirstVisibleCategory()
- }
+ onTriggered: itemLibraryModel.hideCategory(itemsView.currentImport.importUrl,
+ itemsView.currentCategory.categoryName)
}
StudioControls.MenuSeparator {
@@ -184,23 +157,14 @@ Item {
StudioControls.MenuItem {
text: qsTr("Show Module Hidden Categories")
- enabled: itemsView.currentImport && !itemsView.currentImport.importCatVisibleState
- onTriggered: showImportCategories()
+ enabled: itemsView.currentImport && !itemsView.currentImport.allCategoriesVisible
+ onTriggered: itemLibraryModel.showImportHiddenCategories(itemsView.currentImport.importUrl)
}
StudioControls.MenuItem {
text: qsTr("Show All Hidden Categories")
enabled: itemLibraryModel.isAnyCategoryHidden
- onTriggered: {
- if (itemLibraryModel.isAllCategoriesHidden()) {
- itemLibraryModel.showHiddenCategories()
- itemsView.selectedCategory = itemLibraryModel.selectImportFirstVisibleCategory()
- itemLibraryModel.isAnyCategoryHidden = false
- }
-
- itemLibraryModel.isAnyCategoryHidden = false
- itemLibraryModel.showHiddenCategories()
- }
+ onTriggered: itemLibraryModel.showAllHiddenCategories()
}
}
@@ -419,8 +383,6 @@ Item {
onClicked: (mouse) => {
itemLibraryModel.selectImportCategory(parent.parent.currentImportModel.importUrl, model.index)
- itemsView.selectedCategory = model
- itemsView.selectedCategoryImport = parent.parent.currentImportModel
if (mouse.button === Qt.RightButton && !rootView.isSearchActive() && categoryModel.rowCount() !== 1) {
itemsView.currentCategory = model
@@ -428,13 +390,6 @@ Item {
moduleContextMenu.popup()
}
}
- Component.onCompleted: {
- if (categorySelected)
- categorySelected = !categorySelected
- itemsView.selectedCategory = itemLibraryModel.selectImportFirstVisibleCategory()
- if (itemsView.selectedCategory === categorySelected)
- itemsView.selectedCategoryImport = itemsView.selectedCategory.parent.currentImportModel
- }
}
}
}
@@ -473,10 +428,10 @@ Item {
rowSpacing: 7
Repeater {
- model: itemsView.selectedCategory ? itemsView.selectedCategory.itemModel : null
+ model: itemLibraryModel.itemsModel
delegate: ItemDelegate {
visible: itemVisible
- textColor: itemsView.selectedCategoryImport && itemsView.selectedCategoryImport.importUnimported
+ textColor: itemLibraryModel.importUnimportedSelected
? StudioTheme.Values.themeUnimportedModuleColor : StudioTheme.Values.themeTextColor
width: styleConstants.cellWidth + hItemGrid.flexibleWidth
height: styleConstants.cellHeight
diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/ExtendedFunctionLogic.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/ExtendedFunctionLogic.qml
index 748f835614..bdefc13a97 100644
--- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/ExtendedFunctionLogic.qml
+++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/ExtendedFunctionLogic.qml
@@ -164,6 +164,7 @@ Item {
bindingEditor.showWidget()
bindingEditor.text = backendValue.expression
bindingEditor.prepareBindings()
+ bindingEditor.updateWindowName()
}
BindingEditor {
diff --git a/share/qtcreator/qmldesigner/statesEditorQmlSources/StatesDelegate.qml b/share/qtcreator/qmldesigner/statesEditorQmlSources/StatesDelegate.qml
index 5cbefc03d1..2deb46b212 100644
--- a/share/qtcreator/qmldesigner/statesEditorQmlSources/StatesDelegate.qml
+++ b/share/qtcreator/qmldesigner/statesEditorQmlSources/StatesDelegate.qml
@@ -110,6 +110,7 @@ Rectangle {
bindingEditor.showWidget()
bindingEditor.text = delegateWhenConditionString
bindingEditor.prepareBindings()
+ bindingEditor.updateWindowName()
}
}
@@ -309,6 +310,7 @@ Rectangle {
}
stateModelNodeProperty: statesEditorModel.stateModelNode()
+ stateNameProperty: myRoot.delegateStateName
onRejected: {
hideWidget()
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 799d8ef68c..70dfa9b5f6 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -51,8 +51,9 @@ endif()
include(CMakeFindDependencyMacro)
find_dependency(Qt5 ${IDE_QT_VERSION_MIN}
- COMPONENTS Concurrent Core Gui Widgets Core5Compat Network PrintSupport Qml Quick QuickWidgets Sql REQUIRED
+ COMPONENTS Concurrent Core Gui Widgets Core5Compat Network PrintSupport Qml Sql REQUIRED
)
+find_dependency(Qt5 COMPONENTS Quick QuickWidgets QUIET)
if (NOT IDE_VERSION)
include(\${CMAKE_CURRENT_LIST_DIR}/QtCreatorIDEBranding.cmake)
diff --git a/src/libs/3rdparty/syntax-highlighting/.git-blame-ignore-revs b/src/libs/3rdparty/syntax-highlighting/.git-blame-ignore-revs
new file mode 100644
index 0000000000..8b2ba6d3d5
--- /dev/null
+++ b/src/libs/3rdparty/syntax-highlighting/.git-blame-ignore-revs
@@ -0,0 +1,4 @@
+# clang-format
+56ed6f3f5f505eb0dbffc630729d67c3fb510546
+#clang-tidy
+0960472cc3f57831a97697a4ae0cd139e2cc5551
diff --git a/src/libs/3rdparty/syntax-highlighting/.gitignore b/src/libs/3rdparty/syntax-highlighting/.gitignore
index 4d50e82c2d..a29428fe5e 100644
--- a/src/libs/3rdparty/syntax-highlighting/.gitignore
+++ b/src/libs/3rdparty/syntax-highlighting/.gitignore
@@ -9,6 +9,11 @@ callgrind.*
heaptrack.*
/build*/
*.unc-backup*
-.clang-format
-.cmake/
-*.code-workspace \ No newline at end of file
+/.clang-format
+/.cmake/
+/*.code-workspace
+/compile_commands.json
+.clangd
+.idea
+/cmake-build*
+.cache
diff --git a/src/libs/3rdparty/syntax-highlighting/.gitlab-ci.yml b/src/libs/3rdparty/syntax-highlighting/.gitlab-ci.yml
new file mode 100644
index 0000000000..8950fb6d61
--- /dev/null
+++ b/src/libs/3rdparty/syntax-highlighting/.gitlab-ci.yml
@@ -0,0 +1,5 @@
+# SPDX-FileCopyrightText: 2020 Volker Krause <vkrause@kde.org>
+# SPDX-License-Identifier: CC0-1.0
+
+include:
+ - https://invent.kde.org/sysadmin/ci-utilities/raw/master/gitlab-templates/linux.yml
diff --git a/src/libs/3rdparty/syntax-highlighting/.kde-ci.yml b/src/libs/3rdparty/syntax-highlighting/.kde-ci.yml
new file mode 100644
index 0000000000..cf1d3363f9
--- /dev/null
+++ b/src/libs/3rdparty/syntax-highlighting/.kde-ci.yml
@@ -0,0 +1,7 @@
+Dependencies:
+- 'on': ['@all']
+ 'require':
+ 'frameworks/extra-cmake-modules': '@same'
+
+Options:
+ test-before-installing: True
diff --git a/src/libs/3rdparty/syntax-highlighting/CMakeLists.txt b/src/libs/3rdparty/syntax-highlighting/CMakeLists.txt
index 8dc268071a..25f1af3573 100644
--- a/src/libs/3rdparty/syntax-highlighting/CMakeLists.txt
+++ b/src/libs/3rdparty/syntax-highlighting/CMakeLists.txt
@@ -10,11 +10,12 @@ add_qtc_library(KSyntaxHighlighting SHARED
PUBLIC_INCLUDES
src/lib
autogenerated/src/lib
- DEFINES KSYNTAXHIGHLIGHTING_LIBRARY
+ DEFINES KF5SyntaxHighlighting_EXPORTS
DEPENDS Qt5::Network Qt5::Widgets
SOURCES
autogenerated/src/lib/ksyntaxhighlighting_logging.cpp autogenerated/src/lib/ksyntaxhighlighting_logging.h
autogenerated/ksyntaxhighlighting_version.h
+ autogenerated/src/lib/ksyntaxhighlighting_export.h
data/themes/theme-data.qrc
@@ -29,7 +30,6 @@ add_qtc_library(KSyntaxHighlighting SHARED
src/lib/format.cpp src/lib/format.h src/lib/format_p.h
src/lib/htmlhighlighter.cpp src/lib/htmlhighlighter.h
src/lib/keywordlist.cpp src/lib/keywordlist_p.h
- src/lib/ksyntaxhighlighting_export.h
src/lib/matchresult_p.h
src/lib/repository.cpp src/lib/repository.h src/lib/repository_p.h
src/lib/rule.cpp src/lib/rule_p.h
diff --git a/src/libs/3rdparty/syntax-highlighting/README.md b/src/libs/3rdparty/syntax-highlighting/README.md
index 2acff73b18..2e668dd3da 100644
--- a/src/libs/3rdparty/syntax-highlighting/README.md
+++ b/src/libs/3rdparty/syntax-highlighting/README.md
@@ -23,6 +23,8 @@ It's meant as a building block for text editors as well as for simple highlighte
text rendering (e.g. as HTML), supporting both integration with a custom editor
as well as a ready-to-use QSyntaxHighlighter sub-class.
+Besides a C++ API, a [QML API](@ref qml_api) is also provided.
+
## Out of scope
To not turn this into yet another text editor, the following things are considered
@@ -46,7 +48,7 @@ in **data/syntax/** and have the **.xml** extension. Additional ones are
picked up from the file system if present, so you can easily extend this
by application-specific syntax definitions for example.
-To install or test a syntax definiton file locally, place it in
+To install or test a syntax definition file locally, place it in
**org.kde.syntax-highlighting/syntax/**, which is located in your user directory.
Usually it is:
@@ -56,47 +58,56 @@ Usually it is:
<td>$HOME/.local/share/org.kde.syntax-highlighting/syntax/</td>
</tr>
<tr>
- <td>For <a href="https://flathub.org/apps/details/org.kde.kate">Kate's Flatpak package</a></td>
- <td>$HOME/.var/app/org.kde.kate/data/org.kde.syntax-highlighting/syntax/</td>
+ <td>For Flatpak packages</td>
+ <td>$HOME/.var/app/<em>package-name</em>/data/org.kde.syntax-highlighting/syntax/</td>
</tr>
<tr>
- <td>For <a href="https://snapcraft.io/kate">Kate's Snap package</a></td>
- <td>$HOME/snap/kate/current/.local/share/org.kde.syntax-highlighting/syntax/</td>
+ <td>For Snap packages</a></td>
+ <td>$HOME/snap/<em>package-name</em>/current/.local/share/org.kde.syntax-highlighting/syntax/</td>
</tr>
<tr>
<td>On Windows®</td>
<td>&#37;USERPROFILE&#37;&#92;AppData&#92;Local&#92;org.kde.syntax-highlighting&#92;syntax&#92;</td>
</tr>
+ <tr>
+ <td>On macOS®</td>
+ <td>$HOME/Library/Application Support/org.kde.syntax-highlighting/syntax/</td>
+ </tr>
</table>
For more details, see ["The Highlight Definition XML Format" (Working with Syntax Highlighting, KDE Documentation)](https://docs.kde.org/?application=katepart&branch=trunk5&path=highlight.html#katehighlight-xml-format).
-Also, in **data/schema/** there is a script to validate the syntax definiton XML
+Also, in **data/schema/** there is a script to validate the syntax definition XML
files. Use the command `validatehl.sh mySyntax.xml`.
## Color theme files
-This library includes the color themes, the theme files use the **JSON**
-format and are located in **data/themes/** with the **.theme** extension.
+This library includes the color themes, which are documented
+[here](https://docs.kde.org/?application=katepart&branch=trunk5&path=color-themes.html).
+The color theme files use the JSON format and are located in **data/themes/**
+with the **.theme** extension.
Additional ones are also picked up from the file system if present,
in the **org.kde.syntax-highlighting/themes/** folder of your user directory,
-allowing you to easily add custom color theme files.
-The location of **org.kde.syntax-highlighting/themes/** is the same
+allowing you to easily add custom color theme files. This location is the same
as shown in the table of the [previous section](#syntax-definition-files),
replacing the **syntax** folder with **themes**.
+For more details, see ["The Color Themes JSON Format" (Working with Color Themes, KDE Documentation)](https://docs.kde.org/?application=katepart&branch=trunk5&path=color-themes.html#color-themes-json).
The [KTextEditor](https://api.kde.org/frameworks/ktexteditor/html/) library
-(used by Kate, Kile and KDevelop, for example) provides
-a user interface for editing and creating KSyntaxHighlighting color themes, including
+(used by Kate, Kile and KDevelop, for example) provides a
+[user interface](https://docs.kde.org/?application=katepart&branch=trunk5&path=color-themes.html#color-themes-gui)
+for editing and creating KSyntaxHighlighting color themes, including
a tool for exporting and importing the JSON theme files.
+
+Note that in KDE text editors, the KSyntaxHighlighting color themes are used
+[since KDE Frameworks 5.75](https://kate-editor.org/post/2020/2020-09-13-kate-color-themes-5.75/),
+released on October 10, 2020. Previously, Kate's color schemes
+(KConfig based schema config) were used and are now deprecated.
The tool **utils/schema-converter/** and the script **utils/kateschema_to_theme_converter.py**
convert the old Kate schemas to KSyntaxHighlighting themes.
-For more information, see:
-
-* [Kate - Color Themes with Frameworks 5.75 (Kate Editor Website)](https://kate-editor.org/post/2020/2020-09-13-kate-color-themes-5.75/)
-* [Submit a KSyntaxHighlighting Color Theme (Kate Editor Website)](https://kate-editor.org/post/2020/2020-09-18-submit-a-ksyntaxhighlighting-color-theme/)
+Also see ["Submit a KSyntaxHighlighting Color Theme" (Kate Editor Website)](https://kate-editor.org/post/2020/2020-09-18-submit-a-ksyntaxhighlighting-color-theme/).
## Build it
diff --git a/src/libs/3rdparty/syntax-highlighting/autogenerated/autogenerated.pri b/src/libs/3rdparty/syntax-highlighting/autogenerated/autogenerated.pri
index aee620add9..1c540d45be 100644
--- a/src/libs/3rdparty/syntax-highlighting/autogenerated/autogenerated.pri
+++ b/src/libs/3rdparty/syntax-highlighting/autogenerated/autogenerated.pri
@@ -6,4 +6,5 @@ SOURCES += \
HEADERS += \
$$PWD/ksyntaxhighlighting_version.h \
- $$PWD/src/lib/ksyntaxhighlighting_logging.h
+ $$PWD/src/lib/ksyntaxhighlighting_logging.h \
+ $$PWD/src/lib/ksyntaxhighlighting_export.h
diff --git a/src/libs/3rdparty/syntax-highlighting/autogenerated/ksyntaxhighlighting_version.h b/src/libs/3rdparty/syntax-highlighting/autogenerated/ksyntaxhighlighting_version.h
index 32e5aa62a7..a8c5d74235 100644
--- a/src/libs/3rdparty/syntax-highlighting/autogenerated/ksyntaxhighlighting_version.h
+++ b/src/libs/3rdparty/syntax-highlighting/autogenerated/ksyntaxhighlighting_version.h
@@ -3,10 +3,10 @@
#ifndef SyntaxHighlighting_VERSION_H
#define SyntaxHighlighting_VERSION_H
-#define SyntaxHighlighting_VERSION_STRING "5.80.0"
+#define SyntaxHighlighting_VERSION_STRING "5.87.0"
#define SyntaxHighlighting_VERSION_MAJOR 5
-#define SyntaxHighlighting_VERSION_MINOR 80
+#define SyntaxHighlighting_VERSION_MINOR 87
#define SyntaxHighlighting_VERSION_PATCH 0
-#define SyntaxHighlighting_VERSION ((5<<16)|(80<<8)|(0))
+#define SyntaxHighlighting_VERSION ((5<<16)|(87<<8)|(0))
#endif
diff --git a/src/libs/3rdparty/syntax-highlighting/autogenerated/src/lib/WildcardMatcher b/src/libs/3rdparty/syntax-highlighting/autogenerated/src/lib/WildcardMatcher
new file mode 100644
index 0000000000..ecea1b09bd
--- /dev/null
+++ b/src/libs/3rdparty/syntax-highlighting/autogenerated/src/lib/WildcardMatcher
@@ -0,0 +1 @@
+#include "wildcardmatcher.h"
diff --git a/src/libs/3rdparty/syntax-highlighting/autogenerated/src/lib/ksyntaxhighlighting_export.h b/src/libs/3rdparty/syntax-highlighting/autogenerated/src/lib/ksyntaxhighlighting_export.h
new file mode 100644
index 0000000000..1213499635
--- /dev/null
+++ b/src/libs/3rdparty/syntax-highlighting/autogenerated/src/lib/ksyntaxhighlighting_export.h
@@ -0,0 +1,218 @@
+
+#ifndef KSYNTAXHIGHLIGHTING_EXPORT_H
+#define KSYNTAXHIGHLIGHTING_EXPORT_H
+
+#include <QtGlobal>
+
+#ifdef KSYNTAXHIGHLIGHTING_STATIC_DEFINE
+# define KSYNTAXHIGHLIGHTING_EXPORT
+# define KSYNTAXHIGHLIGHTING_NO_EXPORT
+#else
+# ifndef KSYNTAXHIGHLIGHTING_EXPORT
+# ifdef KF5SyntaxHighlighting_EXPORTS
+ /* We are building this library */
+# define KSYNTAXHIGHLIGHTING_EXPORT Q_DECL_EXPORT
+# else
+ /* We are using this library */
+# define KSYNTAXHIGHLIGHTING_EXPORT Q_DECL_IMPORT
+# endif
+# endif
+
+# ifndef KSYNTAXHIGHLIGHTING_NO_EXPORT
+# define KSYNTAXHIGHLIGHTING_NO_EXPORT
+# endif
+#endif
+
+#ifndef KSYNTAXHIGHLIGHTING_DECL_DEPRECATED
+# define KSYNTAXHIGHLIGHTING_DECL_DEPRECATED __declspec(deprecated)
+#endif
+
+#ifndef KSYNTAXHIGHLIGHTING_DECL_DEPRECATED_EXPORT
+# define KSYNTAXHIGHLIGHTING_DECL_DEPRECATED_EXPORT KSYNTAXHIGHLIGHTING_EXPORT KSYNTAXHIGHLIGHTING_DECL_DEPRECATED
+#endif
+
+#ifndef KSYNTAXHIGHLIGHTING_DECL_DEPRECATED_NO_EXPORT
+# define KSYNTAXHIGHLIGHTING_DECL_DEPRECATED_NO_EXPORT KSYNTAXHIGHLIGHTING_NO_EXPORT KSYNTAXHIGHLIGHTING_DECL_DEPRECATED
+#endif
+
+#if 0 /* DEFINE_NO_DEPRECATED */
+# ifndef KSYNTAXHIGHLIGHTING_NO_DEPRECATED
+# define KSYNTAXHIGHLIGHTING_NO_DEPRECATED
+# endif
+#endif
+
+#define KSYNTAXHIGHLIGHTING_DECL_DEPRECATED_TEXT(text) __declspec(deprecated(text))
+
+#define ECM_GENERATEEXPORTHEADER_VERSION_VALUE(major, minor, patch) ((major<<16)|(minor<<8)|(patch))
+
+/* Take any defaults from group settings */
+#if !defined(KSYNTAXHIGHLIGHTING_NO_DEPRECATED) && !defined(KSYNTAXHIGHLIGHTING_DISABLE_DEPRECATED_BEFORE_AND_AT)
+# ifdef KF_NO_DEPRECATED
+# define KSYNTAXHIGHLIGHTING_NO_DEPRECATED
+# elif defined(KF_DISABLE_DEPRECATED_BEFORE_AND_AT)
+# define KSYNTAXHIGHLIGHTING_DISABLE_DEPRECATED_BEFORE_AND_AT KF_DISABLE_DEPRECATED_BEFORE_AND_AT
+# endif
+#endif
+#if !defined(KSYNTAXHIGHLIGHTING_DISABLE_DEPRECATED_BEFORE_AND_AT) && defined(KF_DISABLE_DEPRECATED_BEFORE_AND_AT)
+# define KSYNTAXHIGHLIGHTING_DISABLE_DEPRECATED_BEFORE_AND_AT KF_DISABLE_DEPRECATED_BEFORE_AND_AT
+#endif
+
+#if !defined(KSYNTAXHIGHLIGHTING_NO_DEPRECATED_WARNINGS) && !defined(KSYNTAXHIGHLIGHTING_DEPRECATED_WARNINGS_SINCE)
+# ifdef KF_NO_DEPRECATED_WARNINGS
+# define KSYNTAXHIGHLIGHTING_NO_DEPRECATED_WARNINGS
+# elif defined(KF_DEPRECATED_WARNINGS_SINCE)
+# define KSYNTAXHIGHLIGHTING_DEPRECATED_WARNINGS_SINCE KF_DEPRECATED_WARNINGS_SINCE
+# endif
+#endif
+#if !defined(KSYNTAXHIGHLIGHTING_DEPRECATED_WARNINGS_SINCE) && defined(KF_DEPRECATED_WARNINGS_SINCE)
+# define KSYNTAXHIGHLIGHTING_DEPRECATED_WARNINGS_SINCE KF_DEPRECATED_WARNINGS_SINCE
+#endif
+
+#if defined(KSYNTAXHIGHLIGHTING_NO_DEPRECATED)
+# undef KSYNTAXHIGHLIGHTING_DEPRECATED
+# define KSYNTAXHIGHLIGHTING_DEPRECATED_EXPORT KSYNTAXHIGHLIGHTING_EXPORT
+# define KSYNTAXHIGHLIGHTING_DEPRECATED_NO_EXPORT KSYNTAXHIGHLIGHTING_NO_EXPORT
+#elif defined(KSYNTAXHIGHLIGHTING_NO_DEPRECATED_WARNINGS)
+# define KSYNTAXHIGHLIGHTING_DEPRECATED
+# define KSYNTAXHIGHLIGHTING_DEPRECATED_EXPORT KSYNTAXHIGHLIGHTING_EXPORT
+# define KSYNTAXHIGHLIGHTING_DEPRECATED_NO_EXPORT KSYNTAXHIGHLIGHTING_NO_EXPORT
+#else
+# define KSYNTAXHIGHLIGHTING_DEPRECATED KSYNTAXHIGHLIGHTING_DECL_DEPRECATED
+# define KSYNTAXHIGHLIGHTING_DEPRECATED_EXPORT KSYNTAXHIGHLIGHTING_DECL_DEPRECATED_EXPORT
+# define KSYNTAXHIGHLIGHTING_DEPRECATED_NO_EXPORT KSYNTAXHIGHLIGHTING_DECL_DEPRECATED_NO_EXPORT
+#endif
+
+/* No deprecated API had been removed from build */
+#define KSYNTAXHIGHLIGHTING_EXCLUDE_DEPRECATED_BEFORE_AND_AT 0
+
+#define KSYNTAXHIGHLIGHTING_BUILD_DEPRECATED_SINCE(major, minor) 1
+
+#ifdef KSYNTAXHIGHLIGHTING_NO_DEPRECATED
+# define KSYNTAXHIGHLIGHTING_DISABLE_DEPRECATED_BEFORE_AND_AT 0x55700
+#endif
+#ifdef KSYNTAXHIGHLIGHTING_NO_DEPRECATED_WARNINGS
+# define KSYNTAXHIGHLIGHTING_DEPRECATED_WARNINGS_SINCE 0
+#endif
+
+#ifndef KSYNTAXHIGHLIGHTING_DEPRECATED_WARNINGS_SINCE
+# ifdef KSYNTAXHIGHLIGHTING_DISABLE_DEPRECATED_BEFORE_AND_AT
+# define KSYNTAXHIGHLIGHTING_DEPRECATED_WARNINGS_SINCE KSYNTAXHIGHLIGHTING_DISABLE_DEPRECATED_BEFORE_AND_AT
+# else
+# define KSYNTAXHIGHLIGHTING_DEPRECATED_WARNINGS_SINCE 0x55700
+# endif
+#endif
+
+#ifndef KSYNTAXHIGHLIGHTING_DISABLE_DEPRECATED_BEFORE_AND_AT
+# define KSYNTAXHIGHLIGHTING_DISABLE_DEPRECATED_BEFORE_AND_AT 0
+#endif
+
+#ifdef KSYNTAXHIGHLIGHTING_DEPRECATED
+# define KSYNTAXHIGHLIGHTING_ENABLE_DEPRECATED_SINCE(major, minor) (ECM_GENERATEEXPORTHEADER_VERSION_VALUE(major, minor, 0) > KSYNTAXHIGHLIGHTING_DISABLE_DEPRECATED_BEFORE_AND_AT)
+#else
+# define KSYNTAXHIGHLIGHTING_ENABLE_DEPRECATED_SINCE(major, minor) 0
+#endif
+
+#if KSYNTAXHIGHLIGHTING_DEPRECATED_WARNINGS_SINCE >= 0x55700
+# define KSYNTAXHIGHLIGHTING_DEPRECATED_VERSION_5_87(text) KSYNTAXHIGHLIGHTING_DECL_DEPRECATED_TEXT(text)
+#else
+# define KSYNTAXHIGHLIGHTING_DEPRECATED_VERSION_5_87(text)
+#endif
+#define KSYNTAXHIGHLIGHTING_DEPRECATED_VERSION_5(minor, text) KSYNTAXHIGHLIGHTING_DEPRECATED_VERSION_5_##minor(text)
+#define KSYNTAXHIGHLIGHTING_DEPRECATED_VERSION(major, minor, text) KSYNTAXHIGHLIGHTING_DEPRECATED_VERSION_##major(minor, "Since "#major"."#minor". " text)
+#define KSYNTAXHIGHLIGHTING_DEPRECATED_VERSION_BELATED(major, minor, textmajor, textminor, text) KSYNTAXHIGHLIGHTING_DEPRECATED_VERSION_##major(minor, "Since "#textmajor"."#textminor". " text)
+// Not yet implemented for MSVC
+#define KSYNTAXHIGHLIGHTING_ENUMERATOR_DEPRECATED_VERSION(major, minor, text)
+#define KSYNTAXHIGHLIGHTING_ENUMERATOR_DEPRECATED_VERSION_BELATED(major, minor, textmajor, textminor, text)
+
+#endif /* KSYNTAXHIGHLIGHTING_EXPORT_H */
+
+
+#ifndef ECM_GENERATEEXPORTHEADER_KSYNTAXHIGHLIGHTING_EXPORT_H
+#define ECM_GENERATEEXPORTHEADER_KSYNTAXHIGHLIGHTING_EXPORT_H
+
+
+#define KSYNTAXHIGHLIGHTING_DECL_DEPRECATED_TEXT(text) __declspec(deprecated(text))
+
+#define ECM_GENERATEEXPORTHEADER_VERSION_VALUE(major, minor, patch) ((major<<16)|(minor<<8)|(patch))
+
+/* Take any defaults from group settings */
+#if !defined(KSYNTAXHIGHLIGHTING_NO_DEPRECATED) && !defined(KSYNTAXHIGHLIGHTING_DISABLE_DEPRECATED_BEFORE_AND_AT)
+# ifdef KF_NO_DEPRECATED
+# define KSYNTAXHIGHLIGHTING_NO_DEPRECATED
+# elif defined(KF_DISABLE_DEPRECATED_BEFORE_AND_AT)
+# define KSYNTAXHIGHLIGHTING_DISABLE_DEPRECATED_BEFORE_AND_AT KF_DISABLE_DEPRECATED_BEFORE_AND_AT
+# endif
+#endif
+#if !defined(KSYNTAXHIGHLIGHTING_DISABLE_DEPRECATED_BEFORE_AND_AT) && defined(KF_DISABLE_DEPRECATED_BEFORE_AND_AT)
+# define KSYNTAXHIGHLIGHTING_DISABLE_DEPRECATED_BEFORE_AND_AT KF_DISABLE_DEPRECATED_BEFORE_AND_AT
+#endif
+
+#if !defined(KSYNTAXHIGHLIGHTING_NO_DEPRECATED_WARNINGS) && !defined(KSYNTAXHIGHLIGHTING_DEPRECATED_WARNINGS_SINCE)
+# ifdef KF_NO_DEPRECATED_WARNINGS
+# define KSYNTAXHIGHLIGHTING_NO_DEPRECATED_WARNINGS
+# elif defined(KF_DEPRECATED_WARNINGS_SINCE)
+# define KSYNTAXHIGHLIGHTING_DEPRECATED_WARNINGS_SINCE KF_DEPRECATED_WARNINGS_SINCE
+# endif
+#endif
+#if !defined(KSYNTAXHIGHLIGHTING_DEPRECATED_WARNINGS_SINCE) && defined(KF_DEPRECATED_WARNINGS_SINCE)
+# define KSYNTAXHIGHLIGHTING_DEPRECATED_WARNINGS_SINCE KF_DEPRECATED_WARNINGS_SINCE
+#endif
+
+#if defined(KSYNTAXHIGHLIGHTING_NO_DEPRECATED)
+# undef KSYNTAXHIGHLIGHTING_DEPRECATED
+# define KSYNTAXHIGHLIGHTING_DEPRECATED_EXPORT KSYNTAXHIGHLIGHTING_EXPORT
+# define KSYNTAXHIGHLIGHTING_DEPRECATED_NO_EXPORT KSYNTAXHIGHLIGHTING_NO_EXPORT
+#elif defined(KSYNTAXHIGHLIGHTING_NO_DEPRECATED_WARNINGS)
+# define KSYNTAXHIGHLIGHTING_DEPRECATED
+# define KSYNTAXHIGHLIGHTING_DEPRECATED_EXPORT KSYNTAXHIGHLIGHTING_EXPORT
+# define KSYNTAXHIGHLIGHTING_DEPRECATED_NO_EXPORT KSYNTAXHIGHLIGHTING_NO_EXPORT
+#else
+# define KSYNTAXHIGHLIGHTING_DEPRECATED KSYNTAXHIGHLIGHTING_DECL_DEPRECATED
+# define KSYNTAXHIGHLIGHTING_DEPRECATED_EXPORT KSYNTAXHIGHLIGHTING_DECL_DEPRECATED_EXPORT
+# define KSYNTAXHIGHLIGHTING_DEPRECATED_NO_EXPORT KSYNTAXHIGHLIGHTING_DECL_DEPRECATED_NO_EXPORT
+#endif
+
+/* No deprecated API had been removed from build */
+#define KSYNTAXHIGHLIGHTING_EXCLUDE_DEPRECATED_BEFORE_AND_AT 0
+
+#define KSYNTAXHIGHLIGHTING_BUILD_DEPRECATED_SINCE(major, minor) 1
+
+#ifdef KSYNTAXHIGHLIGHTING_NO_DEPRECATED
+# define KSYNTAXHIGHLIGHTING_DISABLE_DEPRECATED_BEFORE_AND_AT 0x55700
+#endif
+#ifdef KSYNTAXHIGHLIGHTING_NO_DEPRECATED_WARNINGS
+# define KSYNTAXHIGHLIGHTING_DEPRECATED_WARNINGS_SINCE 0
+#endif
+
+#ifndef KSYNTAXHIGHLIGHTING_DEPRECATED_WARNINGS_SINCE
+# ifdef KSYNTAXHIGHLIGHTING_DISABLE_DEPRECATED_BEFORE_AND_AT
+# define KSYNTAXHIGHLIGHTING_DEPRECATED_WARNINGS_SINCE KSYNTAXHIGHLIGHTING_DISABLE_DEPRECATED_BEFORE_AND_AT
+# else
+# define KSYNTAXHIGHLIGHTING_DEPRECATED_WARNINGS_SINCE 0x55700
+# endif
+#endif
+
+#ifndef KSYNTAXHIGHLIGHTING_DISABLE_DEPRECATED_BEFORE_AND_AT
+# define KSYNTAXHIGHLIGHTING_DISABLE_DEPRECATED_BEFORE_AND_AT 0
+#endif
+
+#ifdef KSYNTAXHIGHLIGHTING_DEPRECATED
+# define KSYNTAXHIGHLIGHTING_ENABLE_DEPRECATED_SINCE(major, minor) (ECM_GENERATEEXPORTHEADER_VERSION_VALUE(major, minor, 0) > KSYNTAXHIGHLIGHTING_DISABLE_DEPRECATED_BEFORE_AND_AT)
+#else
+# define KSYNTAXHIGHLIGHTING_ENABLE_DEPRECATED_SINCE(major, minor) 0
+#endif
+
+#if KSYNTAXHIGHLIGHTING_DEPRECATED_WARNINGS_SINCE >= 0x55700
+# define KSYNTAXHIGHLIGHTING_DEPRECATED_VERSION_5_87(text) KSYNTAXHIGHLIGHTING_DECL_DEPRECATED_TEXT(text)
+#else
+# define KSYNTAXHIGHLIGHTING_DEPRECATED_VERSION_5_87(text)
+#endif
+#define KSYNTAXHIGHLIGHTING_DEPRECATED_VERSION_5(minor, text) KSYNTAXHIGHLIGHTING_DEPRECATED_VERSION_5_##minor(text)
+#define KSYNTAXHIGHLIGHTING_DEPRECATED_VERSION(major, minor, text) KSYNTAXHIGHLIGHTING_DEPRECATED_VERSION_##major(minor, "Since "#major"."#minor". " text)
+#define KSYNTAXHIGHLIGHTING_DEPRECATED_VERSION_BELATED(major, minor, textmajor, textminor, text) KSYNTAXHIGHLIGHTING_DEPRECATED_VERSION_##major(minor, "Since "#textmajor"."#textminor". " text)
+// Not yet implemented for MSVC
+#define KSYNTAXHIGHLIGHTING_ENUMERATOR_DEPRECATED_VERSION(major, minor, text)
+#define KSYNTAXHIGHLIGHTING_ENUMERATOR_DEPRECATED_VERSION_BELATED(major, minor, textmajor, textminor, text)
+
+
+#endif /* ECM_GENERATEEXPORTHEADER_KSYNTAXHIGHLIGHTING_EXPORT_H */
diff --git a/src/libs/3rdparty/syntax-highlighting/data/CMakeLists.txt b/src/libs/3rdparty/syntax-highlighting/data/CMakeLists.txt
index 8b923c4795..acc2429ec8 100644
--- a/src/libs/3rdparty/syntax-highlighting/data/CMakeLists.txt
+++ b/src/libs/3rdparty/syntax-highlighting/data/CMakeLists.txt
@@ -38,8 +38,11 @@ generate_syntax_definition(generate-doxygenlua.pl doxygenlua.xml doxygen.xml)
file(GLOB src_defs "${CMAKE_CURRENT_SOURCE_DIR}/syntax/*.xml")
set(defs ${src_defs} ${gen_defs})
+# object library to make cross-folder dependencies work
+add_library(SyntaxHighlightingData OBJECT)
+
# theme data resource
-qt5_add_resources(themes_QRC ${CMAKE_CURRENT_SOURCE_DIR}/themes/theme-data.qrc)
+target_sources(SyntaxHighlightingData PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/themes/theme-data.qrc)
# do we want syntax files bundled in the library?
if (QRC_SYNTAX)
@@ -66,14 +69,10 @@ if (QRC_SYNTAX)
)
set_source_files_properties("${CMAKE_CURRENT_BINARY_DIR}/qrc_syntax-data.cpp" PROPERTIES SKIP_AUTOMOC ON)
- # object library to make cross-folder dependencies work, themes + syntax files
- add_library(SyntaxHighlightingData OBJECT ${themes_QRC} ${CMAKE_CURRENT_BINARY_DIR}/qrc_syntax-data.cpp)
+ target_sources(SyntaxHighlightingData PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/qrc_syntax-data.cpp)
else()
# install the syntax files as normal files into the prefix
install (FILES ${defs} DESTINATION ${KDE_INSTALL_DATADIR}/org.kde.syntax-highlighting/syntax)
-
- # object library to make cross-folder dependencies work, only themes
- add_library(SyntaxHighlightingData OBJECT ${themes_QRC})
endif()
# set PIC to allow use in static and shared libs
diff --git a/src/libs/3rdparty/syntax-highlighting/data/generators/cmake.xml.tpl b/src/libs/3rdparty/syntax-highlighting/data/generators/cmake.xml.tpl
index 8e8d37d266..1c1a3da4ba 100644
--- a/src/libs/3rdparty/syntax-highlighting/data/generators/cmake.xml.tpl
+++ b/src/libs/3rdparty/syntax-highlighting/data/generators/cmake.xml.tpl
@@ -22,7 +22,7 @@
<language
name="CMake"
- version="31"
+ version="<!--{version}-->"
kateversion="5.0"
section="Other"
extensions="CMakeLists.txt;*.cmake;*.cmake.in"
diff --git a/src/libs/3rdparty/syntax-highlighting/data/generators/cmake.yaml b/src/libs/3rdparty/syntax-highlighting/data/generators/cmake.yaml
index 7d4f113cba..ab26c2153b 100644
--- a/src/libs/3rdparty/syntax-highlighting/data/generators/cmake.yaml
+++ b/src/libs/3rdparty/syntax-highlighting/data/generators/cmake.yaml
@@ -1,3 +1,5 @@
+version: 34
+
global-properties:
- ALLOW_DUPLICATE_CUSTOM_TARGETS
- AUTOGEN_SOURCE_GROUP
@@ -56,6 +58,7 @@ directory-properties:
- DEFINITIONS
- EXCLUDE_FROM_ALL
- IMPLICIT_DEPENDS_INCLUDE_TRANSFORM
+ - IMPORTED_TARGETS # Since 3.21
- INCLUDE_DIRECTORIES
- INCLUDE_REGULAR_EXPRESSION
- INTERPROCEDURAL_OPTIMIZATION_<CONFIG>
@@ -172,6 +175,7 @@ target-properties:
- EXCLUDE_FROM_ALL
- EXCLUDE_FROM_DEFAULT_BUILD_<CONFIG>
- EXCLUDE_FROM_DEFAULT_BUILD
+ - EXPORT_COMPILE_COMMANDS # Since 3.20
- EXPORT_NAME
- EXPORT_PROPERTIES # Since 3.12
- FOLDER
@@ -243,6 +247,7 @@ target-properties:
- <LANG>_CPPCHECK # Since 3.10
- <LANG>_CPPLINT
- <LANG>_INCLUDE_WHAT_YOU_USE
+ - <LANG>_LINKER_LAUNCHER # Sine 3.21
- <LANG>_VISIBILITY_PRESET
- LIBRARY_OUTPUT_DIRECTORY_<CONFIG>
- LIBRARY_OUTPUT_DIRECTORY
@@ -284,7 +289,6 @@ target-properties:
- OBJCXX_STANDARD # Since 3.16
- OBJCXX_STANDARD_REQUIRED # Since 3.16
- OPTIMIZE_DEPENDENCIES # Since 3.19
- - OBJC_STANDARD
- OSX_ARCHITECTURES_<CONFIG>
- OSX_ARCHITECTURES
- OSX_CURRENT_VERSION # Since 3.17
@@ -329,6 +333,7 @@ target-properties:
- UNITY_BUILD_CODE_AFTER_INCLUDE # Since 3.16
- UNITY_BUILD_CODE_BEFORE_INCLUDE # Since 3.16
- UNITY_BUILD_MODE # Since 3.18
+ - UNITY_BUILD_UNIQUE_ID # Since 3.20
- VERSION
- VISIBILITY_INLINES_HIDDEN
- VS_CONFIGURATION_TYPE
@@ -372,6 +377,10 @@ target-properties:
- WIN32_EXECUTABLE
- WINDOWS_EXPORT_ALL_SYMBOLS
- XCODE_ATTRIBUTE_<an-attribute>
+ - XCODE_EMBED_<type>_CODE_SIGN_ON_COPY # Since 3.20
+ - XCODE_EMBED_<type>_PATH # Since 3.20
+ - XCODE_EMBED_<type>_REMOVE_HEADERS_ON_COPY # Since 3.20
+ - XCODE_EMBED_<type> # Since 3.20
- XCODE_EXPLICIT_FILE_TYPE
- XCODE_GENERATE_SCHEME # Since 3.15
- XCODE_LINK_BUILD_PHASE_MODE # Since 3.19
@@ -572,6 +581,7 @@ generator-expressions:
- TARGET_BUNDLE_DIR
- TARGET_BUNDLE_CONTENT_DIR
- TARGET_PROPERTY
+ - TARGET_RUNTIME_DLLS # Since 3.21
- INSTALL_PREFIX
# Output-Related Expressions
- TARGET_NAME
@@ -581,6 +591,8 @@ generator-expressions:
- MAKE_C_IDENTIFIER
- TARGET_OBJECTS
- SHELL_PATH
+ - OUTPUT_CONFIG # Since 3.20
+ - COMMAND_CONFIG # Since 3.20
variables:
# Variables that Provide Information
@@ -687,6 +699,7 @@ variables:
- CMAKE_XCODE_PLATFORM_TOOLSET
- <PROJECT-NAME>_BINARY_DIR
- <PROJECT-NAME>_DESCRIPTION # Since 3.12
+ - <PROJECT-NAME>_IS_TOP_LEVEL # Since 3.21
- <PROJECT-NAME>_HOMEPAGE_URL # Since 3.12
- <PROJECT-NAME>_SOURCE_DIR
- <PROJECT-NAME>_VERSION
@@ -696,6 +709,7 @@ variables:
- <PROJECT-NAME>_VERSION_TWEAK
- PROJECT_BINARY_DIR
- PROJECT_DESCRIPTION # Since 3.9
+ - PROJECT_IS_TOP_LEVEL # Since 3.21
- PROJECT_HOMEPAGE_URL # Since 3.12
- PROJECT_NAME
- PROJECT_SOURCE_DIR
@@ -819,6 +833,7 @@ variables:
- ANDROID
- APPLE
- BORLAND
+ - CMAKE_ANDROID_NDK_VERSION # Since 3.20
- CMAKE_CL_64
- CMAKE_COMPILER_2005
- CMAKE_HOST_APPLE
@@ -949,6 +964,9 @@ variables:
- CMAKE_<LANG>_CPPCHECK # Since 3.10
- CMAKE_<LANG>_CPPLINT
- CMAKE_<LANG>_INCLUDE_WHAT_YOU_USE
+ - CMAKE_<LANG>_LINKER_LAUNCHER # Sine 3.21
+ - CMAKE_<LANG>_LINK_LIBRARY_FILE_FLAG # Sine 3.16
+ - CMAKE_<LANG>_LINK_LIBRARY_FLAG # Sine 3.16
- CMAKE_<LANG>_VISIBILITY_PRESET
- CMAKE_LIBRARY_OUTPUT_DIRECTORY
- CMAKE_LIBRARY_OUTPUT_DIRECTORY_<CONFIG>
@@ -1046,6 +1064,7 @@ variables:
- CMAKE_<LANG>_ARCHIVE_APPEND
- CMAKE_<LANG>_ARCHIVE_CREATE
- CMAKE_<LANG>_ARCHIVE_FINISH
+ - CMAKE_<LANG>_BYTE_ORDER # Since 3.20
- CMAKE_<LANG>_COMPILER
- CMAKE_<LANG>_COMPILER_EXTERNAL_TOOLCHAIN
- CMAKE_<LANG>_COMPILER_ID
@@ -1173,6 +1192,7 @@ variables:
# Variables for CPack
- CPACK_ABSOLUTE_DESTINATION_FILES
- CPACK_COMPONENT_INCLUDE_TOPLEVEL_DIRECTORY
+ - CPACK_CUSTOM_INSTALL_VARIABLES # Since 3.21
- CPACK_ERROR_ON_ABSOLUTE_INSTALL_DESTINATION
- CPACK_INCLUDE_TOPLEVEL_DIRECTORY
- CPACK_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS # Since 3.11
@@ -1182,32 +1202,57 @@ variables:
- CPACK_WARN_ON_ABSOLUTE_INSTALL_DESTINATION
# Variables for `find_package()`
- PACKAGE_FIND_NAME
- - PACKAGE_FIND_VERSION
- - PACKAGE_FIND_VERSION_MAJOR
- - PACKAGE_FIND_VERSION_MINOR
- - PACKAGE_FIND_VERSION_PATCH
- - PACKAGE_FIND_VERSION_TWEAK
+ # NOTE <SMTH>_VERSION and components already defined above, so skipped here
- PACKAGE_FIND_VERSION_COUNT
+ - PACKAGE_FIND_VERSION_RANGE
+ - PACKAGE_FIND_VERSION_RANGE_MIN
+ - PACKAGE_FIND_VERSION_RANGE_MAX
+ - PACKAGE_FIND_VERSION_MIN
+ - PACKAGE_FIND_VERSION_MIN_MAJOR
+ - PACKAGE_FIND_VERSION_MIN_MINOR
+ - PACKAGE_FIND_VERSION_MIN_PATCH
+ - PACKAGE_FIND_VERSION_MIN_TWEAK
+ - PACKAGE_FIND_VERSION_MIN_COUNT
+ - PACKAGE_FIND_VERSION_MAX
+ - PACKAGE_FIND_VERSION_MAX_MAJOR
+ - PACKAGE_FIND_VERSION_MAX_MINOR
+ - PACKAGE_FIND_VERSION_MAX_PATCH
+ - PACKAGE_FIND_VERSION_MAX_TWEAK
+ - PACKAGE_FIND_VERSION_MAX_COUNT
+ - PACKAGE_FIND_VERSION_COMPLETE
- PACKAGE_VERSION
- PACKAGE_VERSION_EXACT
- PACKAGE_VERSION_COMPATIBLE
- PACKAGE_VERSION_UNSUITABLE
- # NOTE <SMTH>_VERSION and components already defined above, so skipped here
+ # Package File Interface Variables
- <package>_FOUND
- - <package>_VERSION_COUNT
- <package>_FIND_REQUIRED
- <package>_FIND_QUIETLY
- - <package>_FIND_VERSION
- - <package>_FIND_VERSION_MAJOR
- - <package>_FIND_VERSION_MINOR
- - <package>_FIND_VERSION_PATCH
- - <package>_FIND_VERSION_TWEAK
- - <package>_FIND_VERSION_COUNT
- - <package>_FIND_VERSION_EXACT
- - <package>_FIND_COMPONENTS
- - <package>_FIND_REQUIRED_<c>
- - <package>_CONSIDERED_CONFIGS
- - <package>_CONSIDERED_VERSIONS
+ - <package>_VERSION_COUNT
+ # NOTE <SMTH>_VERSION and components already defined above, so skipped here
+ - <PackageName>_FIND_VERSION_COUNT
+ - <PackageName>_FIND_VERSION_EXACT
+ - <PackageName>_FIND_COMPONENTS
+ - <PackageName>_FIND_REQUIRED_<c>
+ - <PackageName>_FIND_VERSION_RANGE
+ - <PackageName>_FIND_VERSION_RANGE_MIN
+ - <PackageName>_FIND_VERSION_RANGE_MAX
+ - <PackageName>_FIND_VERSION_MIN
+ - <PackageName>_FIND_VERSION_MIN_MAJOR
+ - <PackageName>_FIND_VERSION_MIN_MINOR
+ - <PackageName>_FIND_VERSION_MIN_PATCH
+ - <PackageName>_FIND_VERSION_MIN_TWEAK
+ - <PackageName>_FIND_VERSION_MIN_COUNT
+ - <PackageName>_FIND_VERSION_MAX
+ - <PackageName>_FIND_VERSION_MAX_MAJOR
+ - <PackageName>_FIND_VERSION_MAX_MINOR
+ - <PackageName>_FIND_VERSION_MAX_PATCH
+ - <PackageName>_FIND_VERSION_MAX_TWEAK
+ - <PackageName>_FIND_VERSION_MAX_COUNT
+ - <PackageName>_FIND_VERSION_COMPLETE
+ - <PackageName>_CONFIG
+ - <PackageName>_CONSIDERED_CONFIGS
+ - <PackageName>_CONSIDERED_VERSIONS
- <PackageName>_ROOT # Since 3.12
# Other standard variables/patterns
# - `try_run`
@@ -1220,6 +1265,10 @@ variables:
# - `cmake_parse_arguments`
- <pfx>_UNPARSED_ARGUMENTS
- <pfx>_KEYWORDS_MISSING_VALUES
+ # Variables that control `file(GET_RUNTIME_DEPENDENCIES)` behavior
+ - CMAKE_GET_RUNTIME_DEPENDENCIES_PLATFORM
+ - CMAKE_GET_RUNTIME_DEPENDENCIES_TOOL
+ - CMAKE_GET_RUNTIME_DEPENDENCIES_COMMAND
# Well known CMake's official module's variables
# - CheckCompilerFlag
# - CheckCCompilerFlag
@@ -1327,6 +1376,7 @@ variables:
- CPACK_DEBIAN_PACKAGE_HOMEPAGE
- CPACK_DEBIAN_PACKAGE_SHLIBDEPS
- CPACK_DEBIAN_<COMPONENT>_PACKAGE_SHLIBDEPS
+ - CPACK_DEBIAN_PACKAGE_SHLIBDEPS_PRIVATE_DIRS # Since 3.20
- CPACK_DEBIAN_PACKAGE_DEBUG
- CPACK_DEBIAN_PACKAGE_PREDEPENDS
- CPACK_DEBIAN_<COMPONENT>_PACKAGE_PREDEPENDS
@@ -1364,6 +1414,7 @@ variables:
- CPACK_DMG_SLA_DIR
- CPACK_DMG_SLA_LANGUAGES
- CPACK_DMG_<component>_FILE_NAME # Since 3.17
+ - CPACK_DMG_FILESYSTEM # Since 3.21
- CPACK_COMMAND_HDIUTIL
- CPACK_COMMAND_SETFILE
- CPACK_COMMAND_REZ
@@ -1389,6 +1440,7 @@ variables:
- CPACK_IFW_PACKAGE_STYLE_SHEET # Since 3.15
- CPACK_IFW_PACKAGE_WIZARD_DEFAULT_WIDTH
- CPACK_IFW_PACKAGE_WIZARD_DEFAULT_HEIGHT
+ - CPACK_IFW_PACKAGE_WIZARD_SHOW_PAGE_LIST # Since 3.20
- CPACK_IFW_PACKAGE_TITLE_COLOR
- CPACK_IFW_PACKAGE_START_MENU_DIRECTORY
- CPACK_IFW_TARGET_DIRECTORY
@@ -1443,6 +1495,9 @@ variables:
- CPACK_NSIS_FINISH_TITLE_3LINES # Since 3.17
- CPACK_NSIS_MUI_HEADERIMAGE # Since 3.17
- CPACK_NSIS_MANIFEST_DPI_AWARE # Since 3.18
+ - CPACK_NSIS_BRANDING_TEXT # Since 3.20
+ - CPACK_NSIS_BRANDING_TEXT_TRIM_POSITION # Since 3.20
+ - CPACK_NSIS_EXECUTABLE # Since 3.21
# - CPackNuGet (since 3.12)
- CPACK_NUGET_COMPONENT_INSTALL
- CPACK_NUGET_PACKAGE_NAME
@@ -1461,14 +1516,22 @@ variables:
- CPACK_NUGET_<compName>_PACKAGE_HOMEPAGE_URL
- CPACK_NUGET_PACKAGE_LICENSEURL
- CPACK_NUGET_<compName>_PACKAGE_LICENSEURL
+ - CPACK_NUGET_PACKAGE_LICENSE_EXPRESSION # Since 3.20
+ - CPACK_NUGET_<compName>_PACKAGE_LICENSE_EXPRESSION # Since 3.20
+ - CPACK_NUGET_PACKAGE_LICENSE_FILE_NAME # Since 3.20
+ - CPACK_NUGET_<compName>_PACKAGE_LICENSE_FILE_NAME # Since 3.20
- CPACK_NUGET_PACKAGE_ICONURL
- CPACK_NUGET_<compName>_PACKAGE_ICONURL
+ - CPACK_NUGET_PACKAGE_ICON # Since 3.20
+ - CPACK_NUGET_<compName>_PACKAGE_ICON # Since 3.20
- CPACK_NUGET_PACKAGE_DESCRIPTION_SUMMARY
- CPACK_NUGET_<compName>_PACKAGE_DESCRIPTION_SUMMARY
- CPACK_NUGET_PACKAGE_RELEASE_NOTES
- CPACK_NUGET_<compName>_PACKAGE_RELEASE_NOTES
- CPACK_NUGET_PACKAGE_COPYRIGHT
- CPACK_NUGET_<compName>_PACKAGE_COPYRIGHT
+ - CPACK_NUGET_PACKAGE_LANGUAGE # Since 3.20
+ - CPACK_NUGET_<compName>_PACKAGE_LANGUAGE # Since 3.20
- CPACK_NUGET_PACKAGE_TAGS
- CPACK_NUGET_<compName>_PACKAGE_TAGS
- CPACK_NUGET_PACKAGE_DEPENDENCIES
@@ -1617,6 +1680,7 @@ variables:
- CPACK_PACKAGE_EXECUTABLES
- CPACK_STRIP_FILES
- CPACK_VERBATIM_VARIABLES
+ - CPACK_THREADS # Since 3.20
- CPACK_SOURCE_PACKAGE_FILE_NAME
- CPACK_SOURCE_STRIP_FILES
- CPACK_SOURCE_GENERATOR
@@ -1754,12 +1818,19 @@ variables:
- CMAKE_NO_ANSI_STRING_STREAM
# - TestForSTDNamespace
- CMAKE_NO_STD_NAMESPACE
+ # - UseJava
+ - CMAKE_JAVA_COMPILE_FLAGS
+ - CMAKE_JAVA_INCLUDE_PATH
+ - CMAKE_JNI_TARGET
+ - CMAKE_JAR_CLASSES_PREFIX
# - UseSWIG
+ - UseSWIG_MODULE_VERSION # Since 3.12
- CMAKE_SWIG_FLAGS
- CMAKE_SWIG_OUTDIR
- SWIG_OUTFILE_DIR
- SWIG_MODULE_<name>_EXTRA_DEPS
- SWIG_SOURCE_FILE_EXTENSIONS # Since 3.14
+ - SWIG_USE_SWIG_DEPENDENCIES # Since 3.20
deprecated-or-internal-variables:
- CMAKE_HOME_DIRECTORY
@@ -1784,6 +1855,10 @@ deprecated-or-internal-variables:
- CPACK_TEMPORARY_DIRECTORY
- CPACK_TOPLEVEL_DIRECTORY
- CPACK_INSTALL_PREFIX
+ # Mentioned in `file(GET_RUNTIME_DEPENDENCIES)` docs
+ - CMAKE_OBJDUMP
+ # Mentioned in "Deprecated and Removed Features" of release notes 3.21
+ - CMAKE_SYSTEM_ARCH
# https://cmake.org/cmake/help/latest/manual/cmake-env-variables.7.html
# NOTE Added to syntax file version 14 at 3.15.0 version of CMake
@@ -1801,6 +1876,7 @@ environment-variables:
- CMAKE_MSVCIDE_RUN_PATH
- CMAKE_NO_VERBOSE
- CMAKE_OSX_ARCHITECTURES
+ - CMAKE_TOOLCHAIN_FILE # Since 3.21
- DESTDIR
- LDFLAGS
- MACOSX_DEPLOYMENT_TARGET
@@ -1812,6 +1888,7 @@ environment-variables:
- CC
- CFLAGS
- CSFLAGS
+ - CUDAARCHS # Since 3.20
- CUDACXX
- CUDAFLAGS
- CUDAHOSTCXX
@@ -1897,6 +1974,55 @@ scripting-commands:
name: cmake_parse_arguments
named-args: [PARSE_ARGV]
-
+ name: cmake_path # Since 3.20
+ named-args: [
+ # Decomposition
+ GET
+ , ROOT_NAME
+ , ROOT_DIRECTORY
+ , ROOT_PATH
+ , FILENAME
+ , EXTENSION
+ , LAST_ONLY
+ , STEM
+ , RELATIVE_PART
+ , PARENT_PATH
+ # Query
+ , HAS_ROOT_NAME
+ , HAS_ROOT_DIRECTORY
+ , HAS_ROOT_PATH
+ , HAS_FILENAME
+ , HAS_EXTENSION
+ , HAS_STEM
+ , HAS_RELATIVE_PART
+ , HAS_PARENT_PATH
+ , IS_ABSOLUTE
+ , IS_RELATIVE
+ , IS_PREFIX
+ , NORMALIZE
+ # Modification
+ , SET
+ , APPEND
+ , OUTPUT_VARIABLE
+ , APPEND_STRING
+ , REMOVE_FILENAME
+ , REPLACE_FILENAME
+ , REMOVE_EXTENSION
+ , REPLACE_EXTENSION
+ # Generation
+ , NORMAL_PATH
+ , RELATIVE_PATH
+ , BASE_DIRECTORY
+ , ABSOLUTE_PATH
+ # Native Conversion
+ , NATIVE_PATH
+ , CONVERT
+ , TO_CMAKE_PATH_LIST
+ , TO_NATIVE_PATH_LIST
+ # Hashing
+ , HASH
+ ]
+ -
name: cmake_policy
named-args: [GET, SET, PUSH, POP, VERSION]
special-args: [OLD, NEW]
@@ -1908,6 +2034,8 @@ scripting-commands:
, NO_SOURCE_PERMISSIONS # Since 3.19
, "@ONLY"
, NEWLINE_STYLE
+ , USE_SOURCE_PERMISSIONS # Since 3.20
+ , FILE_PERMISSIONS # Since 3.20
]
special-args: [UNIX, DOS, WIN32, LF, CRLF]
-
@@ -2098,6 +2226,19 @@ scripting-commands:
, SIZE
# New sub-options since 3.16
, GET_RUNTIME_DEPENDENCIES
+ , RESOLVED_DEPENDENCIES_VAR
+ , UNRESOLVED_DEPENDENCIES_VAR
+ , EXECUTABLES
+ , LIBRARIES
+ , MODULES
+ , DIRECTORIES
+ , BUNDLE_EXECUTABLE
+ , PRE_INCLUDE_REGEXES
+ , PRE_EXCLUDE_REGEXES
+ , POST_INCLUDE_REGEXES
+ , POST_EXCLUDE_REGEXES
+ , POST_INCLUDE_FILES # Since 3.21
+ , POST_EXCLUDE_FILES # Since 3.21
# New sub-options since 3.18
, ARCHIVE_CREATE
, FILES
@@ -2112,10 +2253,17 @@ scripting-commands:
, ESCAPE_QUOTES
, "@ONLY"
, NEWLINE_STYLE
- , CHMOD # Since 3.19
- , CHMOD_RECURSE # Since 3.19
- , REAL_PATH # Since 3.19
- , BASE_DIRECTORY # Since 3.19
+ # New sub-options since 3.19
+ , CHMOD
+ , CHMOD_RECURSE
+ , REAL_PATH
+ , BASE_DIRECTORY
+ # New sub-options since 3.21
+ , COPY_FILE
+ , RESULT
+ , ONLY_IF_DIFFERENT
+ , EXPAND_TILDE
+ , NO_REPLACE
]
special-args: [
UTF-8
@@ -2169,6 +2317,7 @@ scripting-commands:
, PATHS
, PATH_SUFFIXES
, DOC
+ , NO_CACHE # Since 3.21
, REQUIRED # Since 3.18
, NO_DEFAULT_PATH
, NO_PACKAGE_ROOT_PATH
@@ -2189,6 +2338,7 @@ scripting-commands:
, PATHS
, PATH_SUFFIXES
, DOC
+ , NO_CACHE # Since 3.21
, REQUIRED # Since 3.18
, NO_DEFAULT_PATH
, NO_PACKAGE_ROOT_PATH
@@ -2595,7 +2745,11 @@ project-commands:
name: aux_source_directory
-
name: build_command
- named-args: [CONFIGURATION, TARGET]
+ named-args: [
+ CONFIGURATION
+ , PARALLEL_LEVEL # Since 3.21
+ , TARGET
+ ]
-
name: create_test_sourcelist
named-args: [EXTRA_INCLUDE, FUNCTION]
@@ -2615,6 +2769,7 @@ project-commands:
, CSharp
, CXX
, CUDA
+ , HIP # Since 3.21
, ISPC # Since 3.19
, Java
, OBJC # Since 3.16
@@ -2664,6 +2819,7 @@ project-commands:
, EXCLUDE_FROM_ALL
, RENAME
, OPTIONAL
+ , TYPE # Since 3.20
# Installing Targets
, TARGETS
, EXPORT
@@ -2679,6 +2835,7 @@ project-commands:
, INCLUDES
, NAMELINK_ONLY
, NAMELINK_SKIP
+ , RUNTIME_DEPENDENCIES # Since 3.21
# Installing Files
, FILES
, PROGRAMS
@@ -2700,6 +2857,17 @@ project-commands:
, FILE
, EXPORT_ANDROID_MK
, EXPORT_LINK_INTERFACE_LIBRARIES
+ # Installing Imported Runtime Artifacts (since 3.21)
+ , IMPORTED_RUNTIME_ARTIFACTS
+ , RUNTIME_DEPENDENCY_SET
+ # Installing Runtime Dependencies (since 3.21)
+ , PRE_INCLUDE_REGEXES
+ , PRE_EXCLUDE_REGEXES
+ , POST_INCLUDE_REGEXES
+ , POST_EXCLUDE_REGEXES
+ , POST_INCLUDE_FILES
+ , POST_EXCLUDE_FILES
+ , DIRECTORIES
]
special-args: &valid_permissions [
OWNER_READ
@@ -2740,6 +2908,7 @@ project-commands:
, CSharp
, CXX
, CUDA
+ , HIP # Since 3.21
, ISPC # Since 3.19
, Java
, OBJC # Since 3.16
@@ -2787,6 +2956,7 @@ project-commands:
, cxx_std_14
, cxx_std_17
, cxx_std_20 # Since 3.12
+ , cxx_std_23 # Since 3.20
, cxx_aggregate_default_initializers
, cxx_alias_templates
, cxx_alignas
@@ -2848,6 +3018,8 @@ project-commands:
, c_std_90
, c_std_99
, c_std_11
+ , c_std_17 # Since 3.21
+ , c_std_23 # Since 3.21
, c_function_prototypes
, c_restrict
, c_static_assert
@@ -2858,13 +3030,21 @@ project-commands:
, cuda_std_14
, cuda_std_17
, cuda_std_20
+ , cuda_std_23 # Since 3.21
]
-
name: target_compile_options
named-args: &target_compile_options [BEFORE, INTERFACE, PUBLIC, PRIVATE]
-
name: target_include_directories
- named-args: [BEFORE, SYSTEM, INTERFACE, PUBLIC, PRIVATE]
+ named-args: [
+ AFTER # Since 3.20
+ , BEFORE
+ , SYSTEM
+ , INTERFACE
+ , PUBLIC
+ , PRIVATE
+ ]
-
# Since 3.13
name: target_link_directories
@@ -2910,6 +3090,7 @@ project-commands:
, COMPILE_OUTPUT_VARIABLE
, RUN_OUTPUT_VARIABLE
, OUTPUT_VARIABLE
+ , WORKING_DIRECTORY # Since 3.20
, ARGS
]
diff --git a/src/libs/3rdparty/syntax-highlighting/data/generators/generate-doxygenlua.pl b/src/libs/3rdparty/syntax-highlighting/data/generators/generate-doxygenlua.pl
new file mode 100644
index 0000000000..ffc38ea17e
--- /dev/null
+++ b/src/libs/3rdparty/syntax-highlighting/data/generators/generate-doxygenlua.pl
@@ -0,0 +1,42 @@
+#!/usr/bin/env perl
+# SPDX-FileCopyrightText: 2020 Jonathan Poelen <jonathan.poelen@gmail.com>
+# SPDX-License-Identifier: MIT
+
+my $file = "";
+
+open(my $input, '<:encoding(UTF-8)', $ARGV[0])
+ or die "Could not open file '$ARGV[0]': $!";
+
+open(my $output, '>:encoding(UTF-8)', $ARGV[1])
+ or die "Could not open file '$ARGV[1]': $!";
+
+while (<$input>)
+{
+ $file .= $_;
+}
+
+$warning = "\n\n<!-- ***** THIS FILE WAS GENERATED BY A SCRIPT - DO NOT EDIT ***** -->\n";
+$first_context = " <context attribute=\"Normal Text\" lineEndContext=\"#stay\" name=\"Normal\">
+ <RegExpr attribute=\"Comment\" context=\"LineComment\" String=\"--(?:!|(?:-(?=[^-]|\$)))\"/>
+ <RegExpr attribute=\"Region\" context=\"#stay\" String=\"--\\s*\@\\{\\s*\$\" beginRegion=\"MemberGroup\" />
+ <RegExpr attribute=\"Region\" context=\"#stay\" String=\"--\\s*\@\\}\\s*\$\" endRegion=\"MemberGroup\" />
+ </context>";
+
+$file =~ s/\n\s*<context [^\n]*?(?:name="ML_|name="BlockComment").*?<\/context>//gs;
+$file =~ s/\n\s*<context [^\n]*?name="Normal".*?<\/context>/\n$first_context/s;
+$file =~ s/\n[^\n]*?(?: ml_word|LineContinue)[^\n]+//gs;
+$file =~ s/\/\/\//---/gs;
+$file =~ s/\/\/!/--!/gs;
+
+$language = $file =~ s/.*?(<language[^>]+?>).*/$1/sr;
+$language =~ s/ name="[^"]+/ name="DoxygenLua/s;
+$language =~ s/ extensions="[^"]+/ extensions="/s;
+$language =~ s/ mimetype="[^"]+/ mimetype="/s;
+$language =~ s/ priority="[^"]+"//s;
+$version = $language =~ s/.*? version="([^"]+).*/$1/sr;
+$version = $version+2;
+$language =~ s/ version="[^"]+/ version="$version/s;
+$file =~ s/<language[^>]+?>/$warning\n$language/s;
+
+print $output $file;
+print $output $warning;
diff --git a/src/libs/3rdparty/syntax-highlighting/data/generators/generate-php.pl b/src/libs/3rdparty/syntax-highlighting/data/generators/generate-php.pl
index a3b20fb554..a516332ef2 100644
--- a/src/libs/3rdparty/syntax-highlighting/data/generators/generate-php.pl
+++ b/src/libs/3rdparty/syntax-highlighting/data/generators/generate-php.pl
@@ -45,6 +45,7 @@ if ($root == 1)
$file =~ s/<language([^>]+)section="[^"]*"/<language$1section="Scripts"/s;
$file =~ s/<language([^>]+)extensions="[^"]*"/<language$1extensions="*.php;*.php3;*.wml;*.phtml;*.phtm;*.inc;*.ctp"/s;
$file =~ s/<language([^>]+)mimetype="[^"]*"/<language$1mimetype="text\/x-php4-src;text\/x-php3-src;text\/vnd.wap.wml;application\/x-php"/s;
+ $file =~ s/<language([^>]+)*/<language$1 indenter="cstyle"/s;
}
else
{
diff --git a/src/libs/3rdparty/syntax-highlighting/data/generators/generate-spdx-syntax.py b/src/libs/3rdparty/syntax-highlighting/data/generators/generate-spdx-syntax.py
new file mode 100644
index 0000000000..73ff29092c
--- /dev/null
+++ b/src/libs/3rdparty/syntax-highlighting/data/generators/generate-spdx-syntax.py
@@ -0,0 +1,67 @@
+#!/usr/bin/env python3
+# -*- coding: utf-8 -*-
+#
+# Generate SPDX-Comments syntax file
+#
+# SPDX-FileCopyrightText: 2020 Alex Turbov <i.zaufi@gmail.com>
+# SPDX-License-Identifier: MIT
+#
+# To install prerequisites:
+#
+# $ pip install --user click jinja2
+#
+# To use:
+#
+# $ ./generate-spdx-syntax.py > ../syntax/spdx-comments.xml
+#
+
+import json
+import pathlib
+import urllib.request
+
+import click
+import jinja2
+
+
+def get_json(url):
+ with urllib.request.urlopen(url=url) as body:
+ return json.load(body)
+
+
+@click.command()
+@click.argument('template', type=click.File('r'), default='./spdx-comments.xml.tpl')
+def cli(template):
+
+ data = {
+ 'licenses': [
+ *filter(
+ lambda l: not l['licenseId'].endswith('+')
+ , get_json(url='https://spdx.org/licenses/licenses.json')['licenses']
+ )
+ ]
+ , 'exceptions': [
+ *filter(
+ lambda l: not l['licenseExceptionId'].endswith('+')
+ , get_json(url='https://spdx.org/licenses/exceptions.json')['exceptions']
+ )
+ ]
+ }
+
+ env = jinja2.Environment(
+ keep_trailing_newline=True
+ )
+ env.block_start_string = '<!--['
+ env.block_end_string = ']-->'
+ env.variable_start_string = '<!--{'
+ env.variable_end_string = '}-->'
+ env.comment_start_string = '<!--#'
+ env.comment_end_string = '#-->'
+
+ tpl = env.from_string(template.read())
+ result = tpl.render(data)
+ print(result.strip(), end=None)
+
+
+if __name__ == '__main__':
+ cli()
+ # TODO Handle execptions and show errors
diff --git a/src/libs/3rdparty/syntax-highlighting/data/generators/spdx-comments.xml.tpl b/src/libs/3rdparty/syntax-highlighting/data/generators/spdx-comments.xml.tpl
new file mode 100644
index 0000000000..58cc80f960
--- /dev/null
+++ b/src/libs/3rdparty/syntax-highlighting/data/generators/spdx-comments.xml.tpl
@@ -0,0 +1,91 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE language SYSTEM "language.dtd">
+<language
+ version="4"
+ kateversion="3.1"
+ name="SPDX-Comments"
+ section="Other"
+ extensions=""
+ mimetype=""
+ author="Alex Turbov (i.zaufi@gmail.com)"
+ license="MIT"
+ hidden="true"
+ >
+ <highlighting>
+ <list name="tags">
+ <item>SPDX-License-Identifier:</item>
+ <item>SPDX-FileContributor:</item>
+ <item>SPDX-FileCopyrightText:</item>
+ <item>SPDX-LicenseInfoInFile:</item>
+ </list>
+
+ <list name="operators">
+ <item>AND</item>
+ <item>OR</item>
+ <item>WITH</item>
+ </list>
+
+ <list name="licenses">
+ <!--[- for license in licenses if not license.isDeprecatedLicenseId ]-->
+ <item><!--{ license.licenseId }--></item>
+ <!--[- endfor ]-->
+ </list>
+
+ <list name="deprecated-licenses">
+ <!--[- for license in licenses if license.isDeprecatedLicenseId ]-->
+ <item><!--{ license.licenseId }--></item>
+ <!--[- endfor ]-->
+ </list>
+
+ <list name="exceptions">
+ <!--[- for exception in exceptions if not exception.isDeprecatedLicenseId ]-->
+ <item><!--{ exception.licenseExceptionId }--></item>
+ <!--[- endfor ]-->
+ </list>
+
+ <list name="deprecated-exceptions">
+ <!--[- for exception in exceptions if exception.isDeprecatedLicenseId ]-->
+ <item><!--{ exception.licenseExceptionId }--></item>
+ <!--[- endfor ]-->
+ </list>
+
+ <contexts>
+
+ <context name="Normal" attribute="SPDX Tag" lineEndContext="#pop">
+ <WordDetect String="SPDX-License-Identifier:" attribute="SPDX Tag" context="license-expression" />
+ <keyword String="tags" attribute="SPDX Tag" />
+ </context>
+
+ <context name="license-expression" attribute="SPDX Value" lineEndContext="#pop" fallthrough="true" fallthroughContext="#pop">
+ <DetectSpaces/>
+ <DetectChar char="(" context="#stay" attribute="SPDX License Expression Operator" />
+ <DetectChar char=")" context="#stay" attribute="SPDX License Expression Operator" />
+ <DetectChar char="+" context="#stay" attribute="SPDX License Expression Operator" />
+ <keyword String="licenses" context="#stay" attribute="SPDX License" />
+ <keyword String="deprecated-licenses" context="#stay" attribute="SPDX Deprecated License" />
+ <keyword String="exceptions" context="#stay" attribute="SPDX License Exception" />
+ <keyword String="deprecated-exceptions" context="#stay" attribute="SPDX Deprecated License Exception" />
+ <keyword String="operators" context="#stay" attribute="SPDX License Expression Operator" />
+ <RegExpr attribute="SPDX License" context="#stay" String="\bLicenseRef-[^\s]+" />
+ </context>
+
+ </contexts>
+
+ <itemDatas>
+ <itemData name="SPDX Tag" defStyleNum="dsAnnotation" italic="true" spellChecking="false" />
+ <itemData name="SPDX Value" defStyleNum="dsAnnotation" italic="true" spellChecking="false" />
+ <itemData name="SPDX License" defStyleNum="dsAnnotation" italic="true" spellChecking="false" />
+ <itemData name="SPDX License Exception" defStyleNum="dsAnnotation" italic="true" spellChecking="false" />
+ <itemData name="SPDX Deprecated License" defStyleNum="dsAnnotation" italic="true" spellChecking="false" />
+ <itemData name="SPDX Deprecated License Exception" defStyleNum="dsAnnotation" italic="true" spellChecking="false" />
+ <itemData name="SPDX License Expression Operator" defStyleNum="dsOperator" italic="true" spellChecking="false" />
+ </itemDatas>
+
+ </highlighting>
+
+ <general>
+ <keywords casesensitive="1" weakDeliminator=":-." />
+ </general>
+
+</language>
+<!-- kate: indent-width 2; -->
diff --git a/src/libs/3rdparty/syntax-highlighting/data/syntax/bash.xml b/src/libs/3rdparty/syntax-highlighting/data/syntax/bash.xml
index d7e4ed3d70..c7b21cb2a0 100644
--- a/src/libs/3rdparty/syntax-highlighting/data/syntax/bash.xml
+++ b/src/libs/3rdparty/syntax-highlighting/data/syntax/bash.xml
@@ -5,7 +5,7 @@
<!ENTITY funcname "([^&_fragpathseps;}=#$]|[+!@](?!\())([^&_fragpathseps;}=$]*+([+!@](?!\())?+)*+">
<!ENTITY varname "[A-Za-z_][A-Za-z0-9_]*">
<!ENTITY eos "(?=$|[ &tab;])"> <!-- eol or space following -->
- <!ENTITY eoexpr "(?=$|[ &tab;&lt;>|&amp;;])">
+ <!ENTITY eoexpr "(?=$|[ &tab;&lt;>|&amp;;)])">
<!ENTITY substseps "${'&quot;`\\">
<!ENTITY symbolseps "&lt;>|&amp;;()"> <!-- see man bash -->
@@ -18,6 +18,13 @@
<!ENTITY opt "(?:[^&_fragpathseps;=/]*+&_fragpathnosep;)*+">
<!ENTITY pathpart "(?:~|\.\.?|&fragpath;)(?:/&path;|(?=[*?]|[+!@]\(|&fragpath;(?:[/*?]|[+!@]\()))|(?:~|\.\.?)(?=[&wordseps;]|$)">
+ <!ENTITY _fragpathseps_alt "*?+!@&substseps;}">
+ <!ENTITY _fragpathnosep_alt "(?:[+!@](?!\()|\\.)?+">
+ <!ENTITY path_alt "(?:[^&_fragpathseps_alt;]*+&_fragpathnosep_alt;)*+">
+ <!ENTITY fragpath_alt "(?:[^&_fragpathseps_alt;/]*+&_fragpathnosep_alt;)*+">
+ <!ENTITY opt_alt "(?:[^&_fragpathseps_alt;=/]*+&_fragpathnosep_alt;)*+">
+ <!ENTITY pathpart_alt "(?:~|\.\.?|&fragpath_alt;)(?:/&path_alt;|(?=[*?]|[+!@]\(|&fragpath_alt;(?:[/*?]|[+!@]\()))|(?:~|\.\.?)(?=\}|$)">
+
<!ENTITY _braceexpansion_spe " &tab;&lt;>|&amp;;{}\\`'&quot;$">
<!ENTITY _brace_noexpansion "\{[^&_braceexpansion_spe;,]*+\}">
<!ENTITY _braceexpansion_var "\$(?:\{[^\[\]&_braceexpansion_spe;]*+(?:\[[*@a-zA-Z0-9]\])\})?">
@@ -28,9 +35,11 @@
<!ENTITY braceexpansion "{&_braceexpansion;">
<!ENTITY heredocq "(?|&quot;([^&quot;]+)&quot;|'([^']+)'|\\(.[^&wordseps;&substseps;]*))">
+
+ <!ENTITY arithmetic_as_subshell "\(((?:[^`'&quot;()$]++|\$\{[^`'&quot;(){}$]+\}|\$(?=[^{`'&quot;()])|`[^`]*+`|\((?1)(?:[)]|(?=['&quot;])))++)(?:[)](?=$|[^)])|[&quot;'])">
]>
-<language name="Bash" version="27" kateversion="5.79" section="Scripts" extensions="*.sh;*.bash;*.ebuild;*.eclass;*.nix;.bashrc;.bash_profile;.bash_login;.profile;PKGBUILD;APKBUILD" mimetype="application/x-shellscript" casesensitive="1" author="Wilbert Berendsen (wilbert@kde.nl)" license="LGPL">
+<language name="Bash" version="30" kateversion="5.79" section="Scripts" extensions="*.sh;*.bash;*.ebuild;*.eclass;*.nix;.bashrc;.bash_profile;.bash_login;.profile;PKGBUILD;APKBUILD" mimetype="application/x-shellscript" casesensitive="1" author="Wilbert Berendsen (wilbert@kde.nl)" license="LGPL">
<!-- (c) 2004 by Wilbert Berendsen (wilbert@kde.nl)
Changes by Matthew Woehlke (mw_triad@users.sourceforge.net)
@@ -40,6 +49,7 @@
<highlighting>
<list name="keywords">
+ <item>break</item>
<item>case</item>
<item>continue</item>
<item>do</item>
@@ -66,7 +76,6 @@
<item>alias</item>
<item>bg</item>
<item>bind</item>
- <item>break</item>
<item>builtin</item>
<item>cd</item>
<item>caller</item>
@@ -458,7 +467,7 @@
<DetectSpaces attribute="Normal Text" context="#stay"/>
<DetectChar attribute="Comment" context="Comment" char="#"/>
<!-- start expression in double parentheses -->
- <Detect2Chars attribute="Keyword" context="ExprDblParen" char="(" char1="(" beginRegion="expression"/>
+ <Detect2Chars context="ExprDblParenOrSubShell" char="(" char1="(" lookAhead="1"/>
<!-- start a subshell -->
<DetectChar attribute="Keyword" context="SubShell" char="(" beginRegion="subshell"/>
<!-- start expression in single/double brackets -->
@@ -554,8 +563,8 @@
</context>
<context attribute="Command" lineEndContext="#pop#pop" name="DispatchSubstVariables">
<Detect2Chars attribute="Parameter Expansion" context="#pop!VarBraceStart" char="$" char1="{"/>
- <StringDetect attribute="Parameter Expansion" context="#pop!ExprDblParenSubst" String="$((" beginRegion="expression"/>
- <Detect2Chars attribute="Parameter Expansion" context="#pop!SubstCommand" char="$" char1="("/>
+ <StringDetect context="#pop!ExprDblParenSubstOrSubstCommand" String="$((" lookAhead="1"/>
+ <Detect2Chars attribute="Parameter Expansion" context="#pop!SubstCommand" char="$" char1="(" beginRegion="subshell"/>
</context>
<context attribute="Command" lineEndContext="#pop#pop" name="DispatchStringVariables">
<Detect2Chars attribute="String SingleQ" context="#pop!StringEsc" char="$" char1="'"/>
@@ -695,27 +704,30 @@
</context>
<context attribute="Path" lineEndContext="#stay" name="ExtGlobAndPop">
<DetectChar attribute="Glob" context="#pop!PathThenPop" char=")"/>
+ <IncludeRules context="FindWord"/>
<IncludeRules context="IncExtGlob"/>
</context>
- <context attribute="Path" lineEndContext="#stay" name="RecursiveExtGlob">
- <DetectChar attribute="Glob" context="#pop" char=")"/>
- <IncludeRules context="IncExtGlob"/>
- </context>
- <context attribute="Path" lineEndContext="#stay" name="IncExtGlob">
+ <context attribute="Path" lineEndContext="#stay" name="FindExtGlob">
<Detect2Chars attribute="Glob" context="RecursiveExtGlob" char="?" char1="("/>
<Detect2Chars attribute="Glob" context="RecursiveExtGlob" char="*" char1="("/>
<Detect2Chars attribute="Glob" context="RecursiveExtGlob" char="+" char1="("/>
<Detect2Chars attribute="Glob" context="RecursiveExtGlob" char="@" char1="("/>
<Detect2Chars attribute="Glob" context="RecursiveExtGlob" char="!" char1="("/>
<AnyChar attribute="Glob" context="#stay" String="|?*"/>
+ </context>
+ <context attribute="Path" lineEndContext="#stay" name="RecursiveExtGlob">
+ <DetectChar attribute="Glob" context="#pop" char=")"/>
<IncludeRules context="FindWord"/>
+ <IncludeRules context="IncExtGlob"/>
+ </context>
+ <context attribute="Path" lineEndContext="#stay" name="IncExtGlob">
+ <IncludeRules context="FindExtGlob"/>
<DetectChar context="PathMaybeBraceExpansion" char="{" lookAhead="1"/>
</context>
<context attribute="Path" lineEndContext="#pop#pop" name="PathThenPop">
<AnyChar context="#pop#pop" String="&wordseps;`" lookAhead="1"/>
<IncludeRules context="FindWord"/>
- <IncludeRules context="FindExtGlobAndPop"/>
- <AnyChar attribute="Glob" context="#stay" String="?*"/>
+ <IncludeRules context="FindExtGlob"/>
<DetectChar context="PathMaybeBraceExpansion" char="{" lookAhead="1"/>
<RegExpr attribute="Path" context="#stay" String="&path;"/>
</context>
@@ -724,6 +736,47 @@
<DetectChar attribute="Path" context="#pop" char="{"/>
</context>
+ <!-- FindPathThenPopInAlternateValue consumes path in ${xx:here}-->
+ <context attribute="Normal Text" lineEndContext="#pop" name="FindPathThenPopInAlternateValue">
+ <IncludeRules context="FindExtGlobAndPopInAlternateValue"/>
+ <AnyChar attribute="Glob" context="PathThenPopInAlternateValue" String="?*"/>
+ <RegExpr attribute="Path" context="PathThenPopInAlternateValue" String="&pathpart_alt;"/>
+ </context>
+ <context attribute="Path" lineEndContext="#stay" name="FindExtGlobAndPopInAlternateValue">
+ <Detect2Chars attribute="Glob" context="ExtGlobAndPopInAlternateValue" char="?" char1="("/>
+ <Detect2Chars attribute="Glob" context="ExtGlobAndPopInAlternateValue" char="*" char1="("/>
+ <Detect2Chars attribute="Glob" context="ExtGlobAndPopInAlternateValue" char="+" char1="("/>
+ <Detect2Chars attribute="Glob" context="ExtGlobAndPopInAlternateValue" char="@" char1="("/>
+ <Detect2Chars attribute="Glob" context="ExtGlobAndPopInAlternateValue" char="!" char1="("/>
+ </context>
+ <context attribute="Path" lineEndContext="#stay" name="FindExtGlobInAlternateValue">
+ <Detect2Chars attribute="Glob" context="RecursiveExtGlobInAlternateValue" char="?" char1="("/>
+ <Detect2Chars attribute="Glob" context="RecursiveExtGlobInAlternateValue" char="*" char1="("/>
+ <Detect2Chars attribute="Glob" context="RecursiveExtGlobInAlternateValue" char="+" char1="("/>
+ <Detect2Chars attribute="Glob" context="RecursiveExtGlobInAlternateValue" char="@" char1="("/>
+ <Detect2Chars attribute="Glob" context="RecursiveExtGlobInAlternateValue" char="!" char1="("/>
+ <AnyChar attribute="Glob" context="#stay" String="|?*"/>
+ </context>
+ <context attribute="Path" lineEndContext="#stay" name="RecursiveExtGlobInAlternateValue">
+ <DetectChar attribute="Glob" context="#pop" char=")"/>
+ <DetectChar context="#pop" char="}" lookAhead="1"/>
+ <IncludeRules context="FindWord"/>
+ <IncludeRules context="FindExtGlobInAlternateValue"/>
+ </context>
+ <context attribute="Path" lineEndContext="#stay" name="ExtGlobAndPopInAlternateValue">
+ <DetectChar attribute="Glob" context="#pop!PathThenPopInAlternateValue" char=")"/>
+ <DetectChar attribute="Error" context="#pop#pop" char="}"/>
+ <IncludeRules context="FindWord"/>
+ <IncludeRules context="FindExtGlobInAlternateValue"/>
+ </context>
+ <context attribute="Path" lineEndContext="#pop#pop" name="PathThenPopInAlternateValue">
+ <DetectChar attribute="Parameter Expansion" context="#pop#pop" char="}"/>
+ <IncludeRules context="FindWord"/>
+ <IncludeRules context="FindExtGlobAndPopInAlternateValue"/>
+ <AnyChar attribute="Glob" context="#stay" String="?*"/>
+ <RegExpr attribute="Path" context="#stay" String="&path_alt;"/>
+ </context>
+
<context attribute="Pattern" lineEndContext="#stay" name="FindPattern">
<Detect2Chars attribute="Glob" context="ExtPattern" char="?" char1="("/>
<Detect2Chars attribute="Glob" context="ExtPattern" char="*" char1="("/>
@@ -1038,7 +1091,7 @@
<!-- SubstCommand is called after a $( is encountered -->
<context attribute="Normal Text" lineEndContext="#stay" name="SubstCommand" fallthroughContext="Command">
- <DetectChar attribute="Parameter Expansion" context="#pop" char=")"/>
+ <DetectChar attribute="Parameter Expansion" context="#pop" char=")" endRegion="subshell"/>
<IncludeRules context="Start"/>
</context>
@@ -1084,7 +1137,7 @@
<Detect2Chars attribute="Parameter Expansion Operator" context="#pop!AlternatePatternValue" char="," char1=","/>
<DetectChar attribute="Parameter Expansion Operator" context="#pop!VarSub" char=":"/>
<DetectChar attribute="Parameter Expansion Operator" context="#pop!VarSubst" char="/"/>
- <AnyChar attribute="Parameter Expansion Operator" context="#pop!AlternateValue" String="%#"/>
+ <AnyChar attribute="Parameter Expansion Operator" context="#pop!AlternateValue" String="-+=?#%"/>
<AnyChar attribute="Parameter Expansion Operator" context="#pop!AlternatePatternValue" String="^,"/>
<DetectChar attribute="Parameter Expansion Operator" context="#pop!VarTransformation" char="@"/>
</context>
@@ -1109,7 +1162,7 @@
<context attribute="Normal Text" lineEndContext="#stay" name="AlternateValue">
<DetectChar attribute="Parameter Expansion" context="#pop" char="}"/>
<IncludeRules context="FindWord"/>
- <IncludeRules context="FindPattern"/>
+ <IncludeRules context="FindPathThenPopInAlternateValue"/>
</context>
<!-- called as soon as ${xxx^ are ${xxx, are encoutered -->
@@ -1125,7 +1178,7 @@
</context>
<context attribute="Pattern" lineEndContext="#stay" name="VarSubstPat">
<DetectChar attribute="Parameter Expansion Operator" context="#pop!AlternateValue" char="/"/>
- <IncludeRules context="AlternateValue"/>
+ <IncludeRules context="AlternatePatternValue"/>
</context>
<!-- called as soon as ${xxx@ is encoutered -->
@@ -1164,19 +1217,26 @@
<!-- ====== These are the contexts that can be branched to ======= -->
+ <context attribute="Normal Text" lineEndContext="#stay" name="ExprDblParenOrSubShell">
+ <RegExpr attribute="Keyword" context="#pop!SubShell" String="\((?=&arithmetic_as_subshell;)|" beginRegion="subshell"/>
+ <Detect2Chars attribute="Keyword" context="#pop!ExprDblParen" char="(" char1="(" beginRegion="expression"/>
+ </context>
<!-- ExprDblParen consumes an expression started in command mode till )) -->
<context attribute="Normal Text" lineEndContext="#stay" name="ExprDblParen">
<DetectSpaces attribute="Normal Text" context="#stay"/>
<Detect2Chars attribute="Keyword" context="#pop" char=")" char1=")" endRegion="expression"/>
<IncludeRules context="FindExprDblParen"/>
+ <!-- ((cmd
+ ) # jump to SubShell context -->
+ <DetectChar attribute="Keyword" context="#pop!SubShell" char=")" endRegion="expression" beginRegion="subshell"/>
</context>
<context attribute="Normal Text" lineEndContext="#stay" name="FindExprDblParen">
<Detect2Chars attribute="Control" context="#stay" char="&amp;" char1="&amp;"/>
<Detect2Chars attribute="Control" context="#stay" char="|" char1="|"/>
<AnyChar attribute="Operator" context="#stay" String="+-!~*/%&lt;>=&amp;^|?:"/>
+ <AnyChar context="Number" String="0123456789" lookAhead="1"/>
<DetectChar attribute="Control" context="#stay" char=","/>
<DetectChar attribute="Normal Text" context="ExprSubDblParen" char="("/>
- <AnyChar context="Number" String="0123456789" lookAhead="1"/>
<DetectChar attribute="Parameter Expansion Operator" context="Subscript" char="["/>
<IncludeRules context="FindWord"/>
<DetectChar attribute="Error" context="#stay" char="#"/>
@@ -1184,8 +1244,9 @@
<DetectIdentifier attribute="Variable" context="#stay"/>
</context>
<context attribute="Normal Text" lineEndContext="#stay" name="ExprSubDblParen">
+ <DetectSpaces attribute="Normal Text" context="#stay"/>
<DetectChar attribute="Normal Text" context="#pop" char=")"/>
- <IncludeRules context="ExprDblParen"/>
+ <IncludeRules context="FindExprDblParen"/>
</context>
<context attribute="Normal Text" lineEndContext="#pop" name="MaybeArithmeticBrace">
<IncludeRules context="DispatchBraceExpansion"/>
@@ -1216,11 +1277,18 @@
<AnyChar attribute="Error" context="#stay" String="8901234567"/>
</context>
+ <context attribute="Normal Text" lineEndContext="#stay" name="ExprDblParenSubstOrSubstCommand">
+ <RegExpr attribute="Parameter Expansion" context="#pop!SubstCommand" String="\$\((?=&arithmetic_as_subshell;)|" beginRegion="subshell"/>
+ <StringDetect attribute="Parameter Expansion" context="#pop!ExprDblParenSubst" String="$((" beginRegion="expression"/>
+ </context>
<!-- ExprDblParenSubst like ExprDblParen but matches )) as Variable -->
<context attribute="Normal Text" lineEndContext="#stay" name="ExprDblParenSubst">
<DetectSpaces attribute="Normal Text" context="#stay"/>
<Detect2Chars attribute="Variable" context="#pop" char=")" char1=")" endRegion="expression"/>
<IncludeRules context="FindExprDblParen"/>
+ <!-- $((cmd
+ ) # jump to SubstCommand context -->
+ <DetectChar attribute="Parameter Expansion" context="#pop!SubstCommand" char=")" endRegion="expression" beginRegion="subshell"/>
</context>
<!-- ExprBracket consumes an expression till ] -->
@@ -1305,7 +1373,7 @@
</context>
<context attribute="Normal Text" lineEndContext="#pop" name="ExprDblBracketValue">
- <Detect2Chars attribute="Keyword" context="ExprDblParen" char="(" char1="(" beginRegion="expression"/>
+ <Detect2Chars context="ExprDblBracketDblParentOrSubValue" char="(" char1="(" lookAhead="1"/>
<DetectChar context="ExprDblBracketSubValue" char="(" lookAhead="1"/>
<DetectChar attribute="Operator" context="#pop#pop" char=")"/>
<Detect2Chars attribute="Control" context="#pop#pop!ExprDblBracket" char="&amp;" char1="&amp;"/>
@@ -1321,6 +1389,18 @@
<DetectChar attribute="Operator" context="ExprDblBracketNot" char="("/>
<Detect2Chars context="#pop#pop" char="]" char1="]" lookAhead="1"/>
</context>
+ <context attribute="Normal Text" lineEndContext="#pop" name="ExprDblBracketDblParentOrSubValue">
+ <RegExpr context="#pop!ExprDblBracketSubValue" String="\((?=&arithmetic_as_subshell;)|" lookAhead="1"/>
+ <Detect2Chars attribute="Keyword" context="#pop!ExprDblBracketExprDblParen" char="(" char1="(" beginRegion="expression"/>
+ </context>
+ <context attribute="Normal Text" lineEndContext="#stay" name="ExprDblBracketExprDblParen">
+ <DetectSpaces attribute="Normal Text" context="#stay"/>
+ <Detect2Chars attribute="Keyword" context="#pop" char=")" char1=")" endRegion="expression"/>
+ <IncludeRules context="FindExprDblParen"/>
+ <!-- ((cmd
+ ) # jump to ExprDblBracketValue context -->
+ <DetectChar attribute="Operator" context="ExprDblBracketValue" char=")" endRegion="expression" beginRegion="subshell"/>
+ </context>
<context attribute="Normal Text" lineEndContext="#stay" name="ExprDblBracketParam2" fallthroughContext="ExprDblBracketValue">
<DetectSpaces attribute="Normal Text" context="#pop!ExprDblBracketParam3"/>
diff --git a/src/libs/3rdparty/syntax-highlighting/data/syntax/cmake.xml b/src/libs/3rdparty/syntax-highlighting/data/syntax/cmake.xml
index 7f3920bfb6..d8676a250d 100644
--- a/src/libs/3rdparty/syntax-highlighting/data/syntax/cmake.xml
+++ b/src/libs/3rdparty/syntax-highlighting/data/syntax/cmake.xml
@@ -22,7 +22,7 @@
<language
name="CMake"
- version="31"
+ version="34"
kateversion="5.0"
section="Other"
extensions="CMakeLists.txt;*.cmake;*.cmake.in"
@@ -39,6 +39,7 @@
<item>cmake_language</item>
<item>cmake_minimum_required</item>
<item>cmake_parse_arguments</item>
+ <item>cmake_path</item>
<item>cmake_policy</item>
<item>configure_file</item>
<item>continue</item>
@@ -196,6 +197,47 @@
<list name="cmake_parse_arguments_nargs">
<item>PARSE_ARGV</item>
</list>
+ <list name="cmake_path_nargs">
+ <item>ABSOLUTE_PATH</item>
+ <item>APPEND</item>
+ <item>APPEND_STRING</item>
+ <item>BASE_DIRECTORY</item>
+ <item>CONVERT</item>
+ <item>EXTENSION</item>
+ <item>FILENAME</item>
+ <item>GET</item>
+ <item>HASH</item>
+ <item>HAS_EXTENSION</item>
+ <item>HAS_FILENAME</item>
+ <item>HAS_PARENT_PATH</item>
+ <item>HAS_RELATIVE_PART</item>
+ <item>HAS_ROOT_DIRECTORY</item>
+ <item>HAS_ROOT_NAME</item>
+ <item>HAS_ROOT_PATH</item>
+ <item>HAS_STEM</item>
+ <item>IS_ABSOLUTE</item>
+ <item>IS_PREFIX</item>
+ <item>IS_RELATIVE</item>
+ <item>LAST_ONLY</item>
+ <item>NATIVE_PATH</item>
+ <item>NORMALIZE</item>
+ <item>NORMAL_PATH</item>
+ <item>OUTPUT_VARIABLE</item>
+ <item>PARENT_PATH</item>
+ <item>RELATIVE_PART</item>
+ <item>RELATIVE_PATH</item>
+ <item>REMOVE_EXTENSION</item>
+ <item>REMOVE_FILENAME</item>
+ <item>REPLACE_EXTENSION</item>
+ <item>REPLACE_FILENAME</item>
+ <item>ROOT_DIRECTORY</item>
+ <item>ROOT_NAME</item>
+ <item>ROOT_PATH</item>
+ <item>SET</item>
+ <item>STEM</item>
+ <item>TO_CMAKE_PATH_LIST</item>
+ <item>TO_NATIVE_PATH_LIST</item>
+ </list>
<list name="cmake_policy_nargs">
<item>GET</item>
<item>POP</item>
@@ -211,8 +253,10 @@
<item>@ONLY</item>
<item>COPYONLY</item>
<item>ESCAPE_QUOTES</item>
+ <item>FILE_PERMISSIONS</item>
<item>NEWLINE_STYLE</item>
<item>NO_SOURCE_PERMISSIONS</item>
+ <item>USE_SOURCE_PERMISSIONS</item>
</list>
<list name="configure_file_sargs">
<item>CRLF</item>
@@ -291,6 +335,7 @@
<item>ARCHIVE_CREATE</item>
<item>ARCHIVE_EXTRACT</item>
<item>BASE_DIRECTORY</item>
+ <item>BUNDLE_EXECUTABLE</item>
<item>CHMOD</item>
<item>CHMOD_RECURSE</item>
<item>COMPRESSION</item>
@@ -300,13 +345,17 @@
<item>CONFIGURE_DEPENDS</item>
<item>CONTENT</item>
<item>COPY</item>
+ <item>COPY_FILE</item>
<item>DESTINATION</item>
+ <item>DIRECTORIES</item>
<item>DIRECTORY</item>
<item>DIRECTORY_PERMISSIONS</item>
<item>DOWNLOAD</item>
<item>ENCODING</item>
<item>ESCAPE_QUOTES</item>
<item>EXCLUDE</item>
+ <item>EXECUTABLES</item>
+ <item>EXPAND_TILDE</item>
<item>EXPECTED_HASH</item>
<item>EXPECTED_MD5</item>
<item>FILES</item>
@@ -327,6 +376,7 @@
<item>INSTALL</item>
<item>LENGTH_MAXIMUM</item>
<item>LENGTH_MINIMUM</item>
+ <item>LIBRARIES</item>
<item>LIMIT</item>
<item>LIMIT_COUNT</item>
<item>LIMIT_INPUT</item>
@@ -337,17 +387,26 @@
<item>LOG</item>
<item>MAKE_DIRECTORY</item>
<item>MD5</item>
+ <item>MODULES</item>
<item>MTIME</item>
<item>NETRC</item>
<item>NETRC_FILE</item>
<item>NEWLINE_CONSUME</item>
<item>NEWLINE_STYLE</item>
<item>NO_HEX_CONVERSION</item>
+ <item>NO_REPLACE</item>
<item>NO_SOURCE_PERMISSIONS</item>
<item>OFFSET</item>
+ <item>ONLY_IF_DIFFERENT</item>
<item>OUTPUT</item>
<item>PATTERN</item>
<item>PERMISSIONS</item>
+ <item>POST_EXCLUDE_FILES</item>
+ <item>POST_EXCLUDE_REGEXES</item>
+ <item>POST_INCLUDE_FILES</item>
+ <item>POST_INCLUDE_REGEXES</item>
+ <item>PRE_EXCLUDE_REGEXES</item>
+ <item>PRE_INCLUDE_REGEXES</item>
<item>READ</item>
<item>READ_SYMLINK</item>
<item>REAL_PATH</item>
@@ -358,6 +417,8 @@
<item>REMOVE</item>
<item>REMOVE_RECURSE</item>
<item>RENAME</item>
+ <item>RESOLVED_DEPENDENCIES_VAR</item>
+ <item>RESULT</item>
<item>RESULT_VARIABLE</item>
<item>SHA1</item>
<item>SHA224</item>
@@ -381,6 +442,7 @@
<item>TOUCH_NOCREATE</item>
<item>TO_CMAKE_PATH</item>
<item>TO_NATIVE_PATH</item>
+ <item>UNRESOLVED_DEPENDENCIES_VAR</item>
<item>UPLOAD</item>
<item>USERPWD</item>
<item>USE_SOURCE_PERMISSIONS</item>
@@ -433,6 +495,7 @@
<item>DOC</item>
<item>HINTS</item>
<item>NAMES</item>
+ <item>NO_CACHE</item>
<item>NO_CMAKE_ENVIRONMENT_PATH</item>
<item>NO_CMAKE_FIND_ROOT_PATH</item>
<item>NO_CMAKE_PATH</item>
@@ -451,6 +514,7 @@
<item>HINTS</item>
<item>NAMES</item>
<item>NAMES_PER_DIR</item>
+ <item>NO_CACHE</item>
<item>NO_CMAKE_ENVIRONMENT_PATH</item>
<item>NO_CMAKE_FIND_ROOT_PATH</item>
<item>NO_CMAKE_PATH</item>
@@ -495,6 +559,7 @@
<item>DOC</item>
<item>HINTS</item>
<item>NAMES</item>
+ <item>NO_CACHE</item>
<item>NO_CMAKE_ENVIRONMENT_PATH</item>
<item>NO_CMAKE_FIND_ROOT_PATH</item>
<item>NO_CMAKE_PATH</item>
@@ -513,6 +578,7 @@
<item>HINTS</item>
<item>NAMES</item>
<item>NAMES_PER_DIR</item>
+ <item>NO_CACHE</item>
<item>NO_CMAKE_ENVIRONMENT_PATH</item>
<item>NO_CMAKE_FIND_ROOT_PATH</item>
<item>NO_CMAKE_PATH</item>
@@ -883,6 +949,7 @@
</list>
<list name="build_command_nargs">
<item>CONFIGURATION</item>
+ <item>PARALLEL_LEVEL</item>
<item>TARGET</item>
</list>
<list name="create_test_sourcelist_nargs">
@@ -914,6 +981,7 @@
<item>CUDA</item>
<item>CXX</item>
<item>Fortran</item>
+ <item>HIP</item>
<item>ISPC</item>
<item>Java</item>
<item>OBJC</item>
@@ -951,6 +1019,7 @@
<item>COMPONENT</item>
<item>CONFIGURATIONS</item>
<item>DESTINATION</item>
+ <item>DIRECTORIES</item>
<item>DIRECTORY</item>
<item>DIRECTORY_PERMISSIONS</item>
<item>EXCLUDE</item>
@@ -963,6 +1032,7 @@
<item>FILES_MATCHING</item>
<item>FILE_PERMISSIONS</item>
<item>FRAMEWORK</item>
+ <item>IMPORTED_RUNTIME_ARTIFACTS</item>
<item>INCLUDES</item>
<item>LIBRARY</item>
<item>MESSAGE_NEVER</item>
@@ -974,6 +1044,12 @@
<item>OPTIONAL</item>
<item>PATTERN</item>
<item>PERMISSIONS</item>
+ <item>POST_EXCLUDE_FILES</item>
+ <item>POST_EXCLUDE_REGEXES</item>
+ <item>POST_INCLUDE_FILES</item>
+ <item>POST_INCLUDE_REGEXES</item>
+ <item>PRE_EXCLUDE_REGEXES</item>
+ <item>PRE_INCLUDE_REGEXES</item>
<item>PRIVATE_HEADER</item>
<item>PROGRAMS</item>
<item>PUBLIC_HEADER</item>
@@ -981,8 +1057,11 @@
<item>RENAME</item>
<item>RESOURCE</item>
<item>RUNTIME</item>
+ <item>RUNTIME_DEPENDENCIES</item>
+ <item>RUNTIME_DEPENDENCY_SET</item>
<item>SCRIPT</item>
<item>TARGETS</item>
+ <item>TYPE</item>
<item>USE_SOURCE_PERMISSIONS</item>
</list>
<list name="install_sargs">
@@ -1028,6 +1107,7 @@
<item>CUDA</item>
<item>CXX</item>
<item>Fortran</item>
+ <item>HIP</item>
<item>ISPC</item>
<item>Java</item>
<item>NONE</item>
@@ -1068,6 +1148,8 @@
<item>c_restrict</item>
<item>c_static_assert</item>
<item>c_std_11</item>
+ <item>c_std_17</item>
+ <item>c_std_23</item>
<item>c_std_90</item>
<item>c_std_99</item>
<item>c_variadic_macros</item>
@@ -1076,6 +1158,7 @@
<item>cuda_std_14</item>
<item>cuda_std_17</item>
<item>cuda_std_20</item>
+ <item>cuda_std_23</item>
<item>cxx_aggregate_default_initializers</item>
<item>cxx_alias_templates</item>
<item>cxx_alignas</item>
@@ -1126,6 +1209,7 @@
<item>cxx_std_14</item>
<item>cxx_std_17</item>
<item>cxx_std_20</item>
+ <item>cxx_std_23</item>
<item>cxx_std_98</item>
<item>cxx_strong_enums</item>
<item>cxx_template_template_parameters</item>
@@ -1146,6 +1230,7 @@
<item>PUBLIC</item>
</list>
<list name="target_include_directories_nargs">
+ <item>AFTER</item>
<item>BEFORE</item>
<item>INTERFACE</item>
<item>PRIVATE</item>
@@ -1201,6 +1286,7 @@
<item>OUTPUT_VARIABLE</item>
<item>RUN_OUTPUT_VARIABLE</item>
<item>RUN_RESULT_VAR</item>
+ <item>WORKING_DIRECTORY</item>
</list>
<list name="ctest_build_nargs">
<item>APPEND</item>
@@ -1342,6 +1428,7 @@
<item>CMAKE_ANDROID_NDK_DEPRECATED_HEADERS</item>
<item>CMAKE_ANDROID_NDK_TOOLCHAIN_HOST_TAG</item>
<item>CMAKE_ANDROID_NDK_TOOLCHAIN_VERSION</item>
+ <item>CMAKE_ANDROID_NDK_VERSION</item>
<item>CMAKE_ANDROID_PROCESS_MAX</item>
<item>CMAKE_ANDROID_PROGUARD</item>
<item>CMAKE_ANDROID_PROGUARD_CONFIG_PATH</item>
@@ -1497,6 +1584,9 @@
<item>CMAKE_GENERATOR_NO_COMPILER_ENV</item>
<item>CMAKE_GENERATOR_PLATFORM</item>
<item>CMAKE_GENERATOR_TOOLSET</item>
+ <item>CMAKE_GET_RUNTIME_DEPENDENCIES_COMMAND</item>
+ <item>CMAKE_GET_RUNTIME_DEPENDENCIES_PLATFORM</item>
+ <item>CMAKE_GET_RUNTIME_DEPENDENCIES_TOOL</item>
<item>CMAKE_GLOBAL_AUTOGEN_TARGET</item>
<item>CMAKE_GLOBAL_AUTOGEN_TARGET_NAME</item>
<item>CMAKE_GLOBAL_AUTORCC_TARGET</item>
@@ -1576,6 +1666,10 @@
<item>CMAKE_ISPC_HEADER_DIRECTORY</item>
<item>CMAKE_ISPC_HEADER_SUFFIX</item>
<item>CMAKE_ISPC_INSTRUCTION_SETS</item>
+ <item>CMAKE_JAR_CLASSES_PREFIX</item>
+ <item>CMAKE_JAVA_COMPILE_FLAGS</item>
+ <item>CMAKE_JAVA_INCLUDE_PATH</item>
+ <item>CMAKE_JNI_TARGET</item>
<item>CMAKE_JOB_POOLS</item>
<item>CMAKE_JOB_POOL_COMPILE</item>
<item>CMAKE_JOB_POOL_LINK</item>
@@ -1787,6 +1881,7 @@
<item>CPACK_COMPONENTS_GROUPING</item>
<item>CPACK_COMPONENT_INCLUDE_TOPLEVEL_DIRECTORY</item>
<item>CPACK_CREATE_DESKTOP_LINKS</item>
+ <item>CPACK_CUSTOM_INSTALL_VARIABLES</item>
<item>CPACK_CYGWIN_BUILD_SCRIPT</item>
<item>CPACK_CYGWIN_PATCH_FILE</item>
<item>CPACK_CYGWIN_PATCH_NUMBER</item>
@@ -1818,6 +1913,7 @@
<item>CPACK_DEBIAN_PACKAGE_REPLACES</item>
<item>CPACK_DEBIAN_PACKAGE_SECTION</item>
<item>CPACK_DEBIAN_PACKAGE_SHLIBDEPS</item>
+ <item>CPACK_DEBIAN_PACKAGE_SHLIBDEPS_PRIVATE_DIRS</item>
<item>CPACK_DEBIAN_PACKAGE_SOURCE</item>
<item>CPACK_DEBIAN_PACKAGE_SUGGESTS</item>
<item>CPACK_DEBIAN_PACKAGE_VERSION</item>
@@ -1826,6 +1922,7 @@
<item>CPACK_DMG_DISABLE_APPLICATIONS_SYMLINK</item>
<item>CPACK_DMG_DS_STORE</item>
<item>CPACK_DMG_DS_STORE_SETUP_SCRIPT</item>
+ <item>CPACK_DMG_FILESYSTEM</item>
<item>CPACK_DMG_FORMAT</item>
<item>CPACK_DMG_SLA_DIR</item>
<item>CPACK_DMG_SLA_LANGUAGES</item>
@@ -1865,6 +1962,7 @@
<item>CPACK_IFW_PACKAGE_WINDOW_ICON</item>
<item>CPACK_IFW_PACKAGE_WIZARD_DEFAULT_HEIGHT</item>
<item>CPACK_IFW_PACKAGE_WIZARD_DEFAULT_WIDTH</item>
+ <item>CPACK_IFW_PACKAGE_WIZARD_SHOW_PAGE_LIST</item>
<item>CPACK_IFW_PACKAGE_WIZARD_STYLE</item>
<item>CPACK_IFW_PRODUCT_URL</item>
<item>CPACK_IFW_REPOGEN_EXECUTABLE</item>
@@ -1880,12 +1978,15 @@
<item>CPACK_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS</item>
<item>CPACK_INSTALL_SCRIPTS</item>
<item>CPACK_MONOLITHIC_INSTALL</item>
+ <item>CPACK_NSIS_BRANDING_TEXT</item>
+ <item>CPACK_NSIS_BRANDING_TEXT_TRIM_POSITION</item>
<item>CPACK_NSIS_COMPRESSOR</item>
<item>CPACK_NSIS_CONTACT</item>
<item>CPACK_NSIS_CREATE_ICONS_EXTRA</item>
<item>CPACK_NSIS_DELETE_ICONS_EXTRA</item>
<item>CPACK_NSIS_DISPLAY_NAME</item>
<item>CPACK_NSIS_ENABLE_UNINSTALL_BEFORE_INSTALL</item>
+ <item>CPACK_NSIS_EXECUTABLE</item>
<item>CPACK_NSIS_EXECUTABLES_DIRECTORY</item>
<item>CPACK_NSIS_EXTRA_INSTALL_COMMANDS</item>
<item>CPACK_NSIS_EXTRA_PREINSTALL_COMMANDS</item>
@@ -1918,8 +2019,12 @@
<item>CPACK_NUGET_PACKAGE_DESCRIPTION</item>
<item>CPACK_NUGET_PACKAGE_DESCRIPTION_SUMMARY</item>
<item>CPACK_NUGET_PACKAGE_HOMEPAGE_URL</item>
+ <item>CPACK_NUGET_PACKAGE_ICON</item>
<item>CPACK_NUGET_PACKAGE_ICONURL</item>
+ <item>CPACK_NUGET_PACKAGE_LANGUAGE</item>
<item>CPACK_NUGET_PACKAGE_LICENSEURL</item>
+ <item>CPACK_NUGET_PACKAGE_LICENSE_EXPRESSION</item>
+ <item>CPACK_NUGET_PACKAGE_LICENSE_FILE_NAME</item>
<item>CPACK_NUGET_PACKAGE_NAME</item>
<item>CPACK_NUGET_PACKAGE_OWNERS</item>
<item>CPACK_NUGET_PACKAGE_RELEASE_NOTES</item>
@@ -2037,6 +2142,7 @@
<item>CPACK_SOURCE_STRIP_FILES</item>
<item>CPACK_STRIP_FILES</item>
<item>CPACK_SYSTEM_NAME</item>
+ <item>CPACK_THREADS</item>
<item>CPACK_TOPLEVEL_TAG</item>
<item>CPACK_VERBATIM_VARIABLES</item>
<item>CPACK_WARN_ON_ABSOLUTE_INSTALL_DESTINATION</item>
@@ -2180,12 +2286,23 @@
<item>MSVC_TOOLSET_VERSION</item>
<item>MSVC_VERSION</item>
<item>PACKAGE_FIND_NAME</item>
- <item>PACKAGE_FIND_VERSION</item>
+ <item>PACKAGE_FIND_VERSION_COMPLETE</item>
<item>PACKAGE_FIND_VERSION_COUNT</item>
- <item>PACKAGE_FIND_VERSION_MAJOR</item>
- <item>PACKAGE_FIND_VERSION_MINOR</item>
- <item>PACKAGE_FIND_VERSION_PATCH</item>
- <item>PACKAGE_FIND_VERSION_TWEAK</item>
+ <item>PACKAGE_FIND_VERSION_MAX</item>
+ <item>PACKAGE_FIND_VERSION_MAX_COUNT</item>
+ <item>PACKAGE_FIND_VERSION_MAX_MAJOR</item>
+ <item>PACKAGE_FIND_VERSION_MAX_MINOR</item>
+ <item>PACKAGE_FIND_VERSION_MAX_PATCH</item>
+ <item>PACKAGE_FIND_VERSION_MAX_TWEAK</item>
+ <item>PACKAGE_FIND_VERSION_MIN</item>
+ <item>PACKAGE_FIND_VERSION_MIN_COUNT</item>
+ <item>PACKAGE_FIND_VERSION_MIN_MAJOR</item>
+ <item>PACKAGE_FIND_VERSION_MIN_MINOR</item>
+ <item>PACKAGE_FIND_VERSION_MIN_PATCH</item>
+ <item>PACKAGE_FIND_VERSION_MIN_TWEAK</item>
+ <item>PACKAGE_FIND_VERSION_RANGE</item>
+ <item>PACKAGE_FIND_VERSION_RANGE_MAX</item>
+ <item>PACKAGE_FIND_VERSION_RANGE_MIN</item>
<item>PACKAGE_VERSION</item>
<item>PACKAGE_VERSION_COMPATIBLE</item>
<item>PACKAGE_VERSION_EXACT</item>
@@ -2196,6 +2313,7 @@
<item>PROJECT_BINARY_DIR</item>
<item>PROJECT_DESCRIPTION</item>
<item>PROJECT_HOMEPAGE_URL</item>
+ <item>PROJECT_IS_TOP_LEVEL</item>
<item>PROJECT_NAME</item>
<item>PROJECT_SOURCE_DIR</item>
<item>PROJECT_VERSION</item>
@@ -2206,8 +2324,10 @@
<item>QTIFWDIR</item>
<item>SWIG_OUTFILE_DIR</item>
<item>SWIG_SOURCE_FILE_EXTENSIONS</item>
+ <item>SWIG_USE_SWIG_DEPENDENCIES</item>
<item>THREADS_PREFER_PTHREAD_FLAG</item>
<item>UNIX</item>
+ <item>UseSWIG_MODULE_VERSION</item>
<item>WIN32</item>
<item>WINCE</item>
<item>WINDOWS_PHONE</item>
@@ -2220,8 +2340,10 @@
<item>CMAKE_HOME_DIRECTORY</item>
<item>CMAKE_INTERNAL_PLATFORM_ABI</item>
<item>CMAKE_NOT_USING_CONFIG_FLAGS</item>
+ <item>CMAKE_OBJDUMP</item>
<item>CMAKE_SUPPRESS_DEVELOPER_ERRORS</item>
<item>CMAKE_SUPPRESS_DEVELOPER_WARNINGS</item>
+ <item>CMAKE_SYSTEM_ARCH</item>
<item>CMAKE_VS_INTEL_Fortran_PROJECT_VERSION</item>
<item>CPACK_INSTALL_PREFIX</item>
<item>CPACK_INSTALL_SCRIPT</item>
@@ -2248,12 +2370,14 @@
<item>CMAKE_NO_VERBOSE</item>
<item>CMAKE_OSX_ARCHITECTURES</item>
<item>CMAKE_PREFIX_PATH</item>
+ <item>CMAKE_TOOLCHAIN_FILE</item>
<item>CSFLAGS</item>
<item>CTEST_INTERACTIVE_DEBUG_MODE</item>
<item>CTEST_OUTPUT_ON_FAILURE</item>
<item>CTEST_PARALLEL_LEVEL</item>
<item>CTEST_PROGRESS_OUTPUT</item>
<item>CTEST_USE_LAUNCHERS_DEFAULT</item>
+ <item>CUDAARCHS</item>
<item>CUDACXX</item>
<item>CUDAFLAGS</item>
<item>CUDAHOSTCXX</item>
@@ -2326,6 +2450,7 @@
<item>DEFINITIONS</item>
<item>EXCLUDE_FROM_ALL</item>
<item>IMPLICIT_DEPENDS_INCLUDE_TRANSFORM</item>
+ <item>IMPORTED_TARGETS</item>
<item>INCLUDE_DIRECTORIES</item>
<item>INCLUDE_REGULAR_EXPRESSION</item>
<item>INTERPROCEDURAL_OPTIMIZATION</item>
@@ -2429,6 +2554,7 @@
<item>ENABLE_EXPORTS</item>
<item>EXCLUDE_FROM_ALL</item>
<item>EXCLUDE_FROM_DEFAULT_BUILD</item>
+ <item>EXPORT_COMPILE_COMMANDS</item>
<item>EXPORT_NAME</item>
<item>EXPORT_PROPERTIES</item>
<item>EchoString</item>
@@ -2554,6 +2680,7 @@
<item>UNITY_BUILD_CODE_AFTER_INCLUDE</item>
<item>UNITY_BUILD_CODE_BEFORE_INCLUDE</item>
<item>UNITY_BUILD_MODE</item>
+ <item>UNITY_BUILD_UNIQUE_ID</item>
<item>VERSION</item>
<item>VISIBILITY_INLINES_HIDDEN</item>
<item>VS_CONFIGURATION_TYPE</item>
@@ -2782,6 +2909,7 @@
<item>TARGET_BUNDLE_DIR</item>
<item>TARGET_BUNDLE_CONTENT_DIR</item>
<item>TARGET_PROPERTY</item>
+ <item>TARGET_RUNTIME_DLLS</item>
<item>INSTALL_PREFIX</item>
<item>TARGET_NAME</item>
<item>LINK_ONLY</item>
@@ -2790,6 +2918,8 @@
<item>MAKE_C_IDENTIFIER</item>
<item>TARGET_OBJECTS</item>
<item>SHELL_PATH</item>
+ <item>OUTPUT_CONFIG</item>
+ <item>COMMAND_CONFIG</item>
</list>
<contexts>
@@ -2801,6 +2931,7 @@
<WordDetect String="cmake_language" insensitive="true" attribute="Command" context="cmake_language_ctx" />
<WordDetect String="cmake_minimum_required" insensitive="true" attribute="Command" context="cmake_minimum_required_ctx" />
<WordDetect String="cmake_parse_arguments" insensitive="true" attribute="Command" context="cmake_parse_arguments_ctx" />
+ <WordDetect String="cmake_path" insensitive="true" attribute="Command" context="cmake_path_ctx" />
<WordDetect String="cmake_policy" insensitive="true" attribute="Command" context="cmake_policy_ctx" />
<WordDetect String="configure_file" insensitive="true" attribute="Command" context="configure_file_ctx" />
<WordDetect String="continue" insensitive="true" attribute="Command" context="continue_ctx" />
@@ -2950,6 +3081,14 @@
<keyword attribute="Named Args" context="#stay" String="cmake_parse_arguments_nargs" />
<IncludeRules context="User Function Args" />
</context>
+ <context attribute="Normal Text" lineEndContext="#stay" name="cmake_path_ctx">
+ <DetectChar attribute="Normal Text" context="cmake_path_ctx_op" char="(" />
+ </context>
+ <context attribute="Normal Text" lineEndContext="#stay" name="cmake_path_ctx_op">
+ <IncludeRules context="EndCmdPop2" />
+ <keyword attribute="Named Args" context="#stay" String="cmake_path_nargs" />
+ <IncludeRules context="User Function Args" />
+ </context>
<context attribute="Normal Text" lineEndContext="#stay" name="cmake_policy_ctx">
<DetectChar attribute="Normal Text" context="cmake_policy_ctx_op" char="(" />
</context>
@@ -3860,7 +3999,7 @@
</context>
<context attribute="Normal Text" lineEndContext="#stay" name="Detect More target-properties">
- <RegExpr attribute="Property" context="#stay" String="\b(?:XCODE_ATTRIBUTE_&id_re;|VS_SOURCE_SETTINGS_&id_re;|VS_GLOBAL_&id_re;|VS_DOTNET_REFERENCE_&id_re;|VS_DOTNET_REFERENCEPROP_&id_re;_TAG_&id_re;|STATIC_LIBRARY_FLAGS_&id_re;|RUNTIME_OUTPUT_NAME_&id_re;|RUNTIME_OUTPUT_DIRECTORY_&id_re;|PDB_OUTPUT_DIRECTORY_&id_re;|PDB_NAME_&id_re;|OUTPUT_NAME_&id_re;|OSX_ARCHITECTURES_&id_re;|MAP_IMPORTED_CONFIG_&id_re;|LOCATION_&id_re;|LINK_INTERFACE_MULTIPLICITY_&id_re;|LINK_INTERFACE_LIBRARIES_&id_re;|LINK_FLAGS_&id_re;|LIBRARY_OUTPUT_NAME_&id_re;|LIBRARY_OUTPUT_DIRECTORY_&id_re;|INTERPROCEDURAL_OPTIMIZATION_&id_re;|IMPORTED_SONAME_&id_re;|IMPORTED_OBJECTS_&id_re;|IMPORTED_NO_SONAME_&id_re;|IMPORTED_LOCATION_&id_re;|IMPORTED_LINK_INTERFACE_MULTIPLICITY_&id_re;|IMPORTED_LINK_INTERFACE_LIBRARIES_&id_re;|IMPORTED_LINK_INTERFACE_LANGUAGES_&id_re;|IMPORTED_LINK_DEPENDENT_LIBRARIES_&id_re;|IMPORTED_LIBNAME_&id_re;|IMPORTED_IMPLIB_&id_re;|FRAMEWORK_MULTI_CONFIG_POSTFIX_&id_re;|EXCLUDE_FROM_DEFAULT_BUILD_&id_re;|COMPILE_PDB_OUTPUT_DIRECTORY_&id_re;|COMPILE_PDB_NAME_&id_re;|ARCHIVE_OUTPUT_NAME_&id_re;|ARCHIVE_OUTPUT_DIRECTORY_&id_re;|&id_re;_VISIBILITY_PRESET|&id_re;_POSTFIX|&id_re;_OUTPUT_NAME|&id_re;_INCLUDE_WHAT_YOU_USE|&id_re;_CPPLINT|&id_re;_CPPCHECK|&id_re;_COMPILER_LAUNCHER|&id_re;_CLANG_TIDY)\b" />
+ <RegExpr attribute="Property" context="#stay" String="\b(?:XCODE_EMBED_&id_re;_REMOVE_HEADERS_ON_COPY|XCODE_EMBED_&id_re;_PATH|XCODE_EMBED_&id_re;_CODE_SIGN_ON_COPY|XCODE_EMBED_&id_re;|XCODE_ATTRIBUTE_&id_re;|VS_SOURCE_SETTINGS_&id_re;|VS_GLOBAL_&id_re;|VS_DOTNET_REFERENCE_&id_re;|VS_DOTNET_REFERENCEPROP_&id_re;_TAG_&id_re;|STATIC_LIBRARY_FLAGS_&id_re;|RUNTIME_OUTPUT_NAME_&id_re;|RUNTIME_OUTPUT_DIRECTORY_&id_re;|PDB_OUTPUT_DIRECTORY_&id_re;|PDB_NAME_&id_re;|OUTPUT_NAME_&id_re;|OSX_ARCHITECTURES_&id_re;|MAP_IMPORTED_CONFIG_&id_re;|LOCATION_&id_re;|LINK_INTERFACE_MULTIPLICITY_&id_re;|LINK_INTERFACE_LIBRARIES_&id_re;|LINK_FLAGS_&id_re;|LIBRARY_OUTPUT_NAME_&id_re;|LIBRARY_OUTPUT_DIRECTORY_&id_re;|INTERPROCEDURAL_OPTIMIZATION_&id_re;|IMPORTED_SONAME_&id_re;|IMPORTED_OBJECTS_&id_re;|IMPORTED_NO_SONAME_&id_re;|IMPORTED_LOCATION_&id_re;|IMPORTED_LINK_INTERFACE_MULTIPLICITY_&id_re;|IMPORTED_LINK_INTERFACE_LIBRARIES_&id_re;|IMPORTED_LINK_INTERFACE_LANGUAGES_&id_re;|IMPORTED_LINK_DEPENDENT_LIBRARIES_&id_re;|IMPORTED_LIBNAME_&id_re;|IMPORTED_IMPLIB_&id_re;|FRAMEWORK_MULTI_CONFIG_POSTFIX_&id_re;|EXCLUDE_FROM_DEFAULT_BUILD_&id_re;|COMPILE_PDB_OUTPUT_DIRECTORY_&id_re;|COMPILE_PDB_NAME_&id_re;|ARCHIVE_OUTPUT_NAME_&id_re;|ARCHIVE_OUTPUT_DIRECTORY_&id_re;|&id_re;_VISIBILITY_PRESET|&id_re;_POSTFIX|&id_re;_OUTPUT_NAME|&id_re;_LINKER_LAUNCHER|&id_re;_INCLUDE_WHAT_YOU_USE|&id_re;_CPPLINT|&id_re;_CPPCHECK|&id_re;_COMPILER_LAUNCHER|&id_re;_CLANG_TIDY)\b" />
</context>
<context attribute="Normal Text" lineEndContext="#stay" name="Detect More source-properties">
@@ -3894,7 +4033,7 @@
<context attribute="Normal Text" lineEndContext="#stay" name="Detect More Builtin Variables">
<RegExpr attribute="CMake Internal Variable" context="#stay" String="\b(?:CMAKE_&id_re;_PLATFORM_ID|CMAKE_&id_re;_COMPILER_VERSION_INTERNAL|CMAKE_&id_re;_COMPILER_ARCHITECTURE_ID|CMAKE_&id_re;_COMPILER_ABI)\b" />
- <RegExpr attribute="Builtin Variable" context="#stay" String="\b(?:SWIG_MODULE_&id_re;_EXTRA_DEPS|ExternalData_URL_ALGO_&id_re;_&id_re;|ExternalData_CUSTOM_SCRIPT_&id_re;|DOXYGEN_&id_re;|CPACK_WIX_PROPERTY_&id_re;|CPACK_WIX_&id_re;_EXTRA_FLAGS|CPACK_WIX_&id_re;_EXTENSIONS|CPACK_RPM_NO_&id_re;_INSTALL_PREFIX_RELOCATION|CPACK_RPM_&id_re;_USER_FILELIST|CPACK_RPM_&id_re;_USER_BINARY_SPECFILE|CPACK_RPM_&id_re;_PACKAGE_URL|CPACK_RPM_&id_re;_PACKAGE_SUMMARY|CPACK_RPM_&id_re;_PACKAGE_SUGGESTS|CPACK_RPM_&id_re;_PACKAGE_REQUIRES_PREUN|CPACK_RPM_&id_re;_PACKAGE_REQUIRES_PRE|CPACK_RPM_&id_re;_PACKAGE_REQUIRES_POSTUN|CPACK_RPM_&id_re;_PACKAGE_REQUIRES_POST|CPACK_RPM_&id_re;_PACKAGE_REQUIRES|CPACK_RPM_&id_re;_PACKAGE_PROVIDES|CPACK_RPM_&id_re;_PACKAGE_PREFIX|CPACK_RPM_&id_re;_PACKAGE_OBSOLETES|CPACK_RPM_&id_re;_PACKAGE_NAME|CPACK_RPM_&id_re;_PACKAGE_GROUP|CPACK_RPM_&id_re;_PACKAGE_DESCRIPTION|CPACK_RPM_&id_re;_PACKAGE_CONFLICTS|CPACK_RPM_&id_re;_PACKAGE_AUTOREQPROV|CPACK_RPM_&id_re;_PACKAGE_AUTOREQ|CPACK_RPM_&id_re;_PACKAGE_AUTOPROV|CPACK_RPM_&id_re;_PACKAGE_ARCHITECTURE|CPACK_RPM_&id_re;_FILE_NAME|CPACK_RPM_&id_re;_DEFAULT_USER|CPACK_RPM_&id_re;_DEFAULT_GROUP|CPACK_RPM_&id_re;_DEFAULT_FILE_PERMISSIONS|CPACK_RPM_&id_re;_DEFAULT_DIR_PERMISSIONS|CPACK_RPM_&id_re;_DEBUGINFO_PACKAGE|CPACK_RPM_&id_re;_DEBUGINFO_FILE_NAME|CPACK_RPM_&id_re;_BUILD_SOURCE_DIRS_PREFIX|CPACK_PREFLIGHT_&id_re;_SCRIPT|CPACK_POSTFLIGHT_&id_re;_SCRIPT|CPACK_NUGET_PACKAGE_DEPENDENCIES_&id_re;_VERSION|CPACK_NUGET_&id_re;_PACKAGE_VERSION|CPACK_NUGET_&id_re;_PACKAGE_TITLE|CPACK_NUGET_&id_re;_PACKAGE_TAGS|CPACK_NUGET_&id_re;_PACKAGE_RELEASE_NOTES|CPACK_NUGET_&id_re;_PACKAGE_OWNERS|CPACK_NUGET_&id_re;_PACKAGE_NAME|CPACK_NUGET_&id_re;_PACKAGE_LICENSEURL|CPACK_NUGET_&id_re;_PACKAGE_ICONURL|CPACK_NUGET_&id_re;_PACKAGE_HOMEPAGE_URL|CPACK_NUGET_&id_re;_PACKAGE_DESCRIPTION_SUMMARY|CPACK_NUGET_&id_re;_PACKAGE_DESCRIPTION|CPACK_NUGET_&id_re;_PACKAGE_DEPENDENCIES_&id_re;_VERSION|CPACK_NUGET_&id_re;_PACKAGE_DEPENDENCIES|CPACK_NUGET_&id_re;_PACKAGE_COPYRIGHT|CPACK_NUGET_&id_re;_PACKAGE_AUTHORS|CPACK_NSIS_&id_re;_INSTALL_DIRECTORY|CPACK_DMG_&id_re;_FILE_NAME|CPACK_DEBIAN_&id_re;_PACKAGE_SUGGESTS|CPACK_DEBIAN_&id_re;_PACKAGE_SOURCE|CPACK_DEBIAN_&id_re;_PACKAGE_SHLIBDEPS|CPACK_DEBIAN_&id_re;_PACKAGE_SECTION|CPACK_DEBIAN_&id_re;_PACKAGE_REPLACES|CPACK_DEBIAN_&id_re;_PACKAGE_RECOMMENDS|CPACK_DEBIAN_&id_re;_PACKAGE_PROVIDES|CPACK_DEBIAN_&id_re;_PACKAGE_PRIORITY|CPACK_DEBIAN_&id_re;_PACKAGE_PREDEPENDS|CPACK_DEBIAN_&id_re;_PACKAGE_NAME|CPACK_DEBIAN_&id_re;_PACKAGE_ENHANCES|CPACK_DEBIAN_&id_re;_PACKAGE_DEPENDS|CPACK_DEBIAN_&id_re;_PACKAGE_CONTROL_STRICT_PERMISSION|CPACK_DEBIAN_&id_re;_PACKAGE_CONTROL_EXTRA|CPACK_DEBIAN_&id_re;_PACKAGE_CONFLICTS|CPACK_DEBIAN_&id_re;_PACKAGE_BREAKS|CPACK_DEBIAN_&id_re;_PACKAGE_ARCHITECTURE|CPACK_DEBIAN_&id_re;_FILE_NAME|CPACK_DEBIAN_&id_re;_DESCRIPTION|CPACK_DEBIAN_&id_re;_DEBUGINFO_PACKAGE|CPACK_COMPONENT_&id_re;_REQUIRED|CPACK_COMPONENT_&id_re;_HIDDEN|CPACK_COMPONENT_&id_re;_GROUP|CPACK_COMPONENT_&id_re;_DISPLAY_NAME|CPACK_COMPONENT_&id_re;_DISABLED|CPACK_COMPONENT_&id_re;_DESCRIPTION|CPACK_COMPONENT_&id_re;_DEPENDS|CPACK_BINARY_&id_re;|CPACK_ARCHIVE_&id_re;_FILE_NAME|CPACK_&id_re;_COMPONENT_INSTALL|CMAKE_XCODE_ATTRIBUTE_&id_re;|CMAKE_USER_MAKE_RULES_OVERRIDE_&id_re;|CMAKE_STATIC_LINKER_FLAGS_&id_re;_INIT|CMAKE_STATIC_LINKER_FLAGS_&id_re;|CMAKE_SHARED_LINKER_FLAGS_&id_re;_INIT|CMAKE_SHARED_LINKER_FLAGS_&id_re;|CMAKE_RUNTIME_OUTPUT_DIRECTORY_&id_re;|CMAKE_PROJECT_&id_re;_INCLUDE|CMAKE_POLICY_WARNING_CMP[0-9]{4}|CMAKE_POLICY_DEFAULT_CMP[0-9]{4}|CMAKE_PDB_OUTPUT_DIRECTORY_&id_re;|CMAKE_MODULE_LINKER_FLAGS_&id_re;_INIT|CMAKE_MODULE_LINKER_FLAGS_&id_re;|CMAKE_MATCH_[0-9]+|CMAKE_MAP_IMPORTED_CONFIG_&id_re;|CMAKE_LIBRARY_OUTPUT_DIRECTORY_&id_re;|CMAKE_INTERPROCEDURAL_OPTIMIZATION_&id_re;|CMAKE_FRAMEWORK_MULTI_CONFIG_POSTFIX_&id_re;|CMAKE_EXE_LINKER_FLAGS_&id_re;_INIT|CMAKE_EXE_LINKER_FLAGS_&id_re;|CMAKE_DISABLE_FIND_PACKAGE_&id_re;|CMAKE_COMPILE_PDB_OUTPUT_DIRECTORY_&id_re;|CMAKE_ARGV[0-9]+|CMAKE_ARCHIVE_OUTPUT_DIRECTORY_&id_re;|CMAKE_&id_re;_VISIBILITY_PRESET|CMAKE_&id_re;_STANDARD_LIBRARIES|CMAKE_&id_re;_STANDARD_INCLUDE_DIRECTORIES|CMAKE_&id_re;_SOURCE_FILE_EXTENSIONS|CMAKE_&id_re;_SIZEOF_DATA_PTR|CMAKE_&id_re;_SIMULATE_VERSION|CMAKE_&id_re;_SIMULATE_ID|CMAKE_&id_re;_POSTFIX|CMAKE_&id_re;_OUTPUT_EXTENSION|CMAKE_&id_re;_LINK_EXECUTABLE|CMAKE_&id_re;_LINKER_WRAPPER_FLAG_SEP|CMAKE_&id_re;_LINKER_WRAPPER_FLAG|CMAKE_&id_re;_LINKER_PREFERENCE_PROPAGATES|CMAKE_&id_re;_LINKER_PREFERENCE|CMAKE_&id_re;_LIBRARY_ARCHITECTURE|CMAKE_&id_re;_INCLUDE_WHAT_YOU_USE|CMAKE_&id_re;_IMPLICIT_LINK_LIBRARIES|CMAKE_&id_re;_IMPLICIT_LINK_FRAMEWORK_DIRECTORIES|CMAKE_&id_re;_IMPLICIT_LINK_DIRECTORIES|CMAKE_&id_re;_IMPLICIT_INCLUDE_DIRECTORIES|CMAKE_&id_re;_IGNORE_EXTENSIONS|CMAKE_&id_re;_GHS_KERNEL_FLAGS_RELWITHDEBINFO|CMAKE_&id_re;_GHS_KERNEL_FLAGS_RELEASE|CMAKE_&id_re;_GHS_KERNEL_FLAGS_MINSIZEREL|CMAKE_&id_re;_GHS_KERNEL_FLAGS_DEBUG|CMAKE_&id_re;_FLAGS_RELWITHDEBINFO_INIT|CMAKE_&id_re;_FLAGS_RELWITHDEBINFO|CMAKE_&id_re;_FLAGS_RELEASE_INIT|CMAKE_&id_re;_FLAGS_RELEASE|CMAKE_&id_re;_FLAGS_MINSIZEREL_INIT|CMAKE_&id_re;_FLAGS_MINSIZEREL|CMAKE_&id_re;_FLAGS_INIT|CMAKE_&id_re;_FLAGS_DEBUG_INIT|CMAKE_&id_re;_FLAGS_DEBUG|CMAKE_&id_re;_FLAGS|CMAKE_&id_re;_CREATE_STATIC_LIBRARY|CMAKE_&id_re;_CREATE_SHARED_MODULE|CMAKE_&id_re;_CREATE_SHARED_LIBRARY|CMAKE_&id_re;_CPPLINT|CMAKE_&id_re;_CPPCHECK|CMAKE_&id_re;_COMPILE_OBJECT|CMAKE_&id_re;_COMPILER_VERSION|CMAKE_&id_re;_COMPILER_TARGET|CMAKE_&id_re;_COMPILER_RANLIB|CMAKE_&id_re;_COMPILER_LOADED|CMAKE_&id_re;_COMPILER_LAUNCHER|CMAKE_&id_re;_COMPILER_ID|CMAKE_&id_re;_COMPILER_EXTERNAL_TOOLCHAIN|CMAKE_&id_re;_COMPILER_AR|CMAKE_&id_re;_COMPILER|CMAKE_&id_re;_CLANG_TIDY|CMAKE_&id_re;_ARCHIVE_FINISH|CMAKE_&id_re;_ARCHIVE_CREATE|CMAKE_&id_re;_ARCHIVE_APPEND|CMAKE_&id_re;_ANDROID_TOOLCHAIN_SUFFIX|CMAKE_&id_re;_ANDROID_TOOLCHAIN_PREFIX|CMAKE_&id_re;_ANDROID_TOOLCHAIN_MACHINE|ARGV[0-9]+|&id_re;__TRYRUN_OUTPUT|&id_re;_VERSION_TWEAK|&id_re;_VERSION_STRING|&id_re;_VERSION_PATCH|&id_re;_VERSION_MINOR|&id_re;_VERSION_MAJOR|&id_re;_VERSION_COUNT|&id_re;_VERSION|&id_re;_UNPARSED_ARGUMENTS|&id_re;_SOURCE_DIR|&id_re;_ROOT|&id_re;_MODULE_NAME|&id_re;_LIBRARY_DIRS|&id_re;_LIBRARIES|&id_re;_KEYWORDS_MISSING_VALUES|&id_re;_INCLUDE_DIRS|&id_re;_HOMEPAGE_URL|&id_re;_FOUND|&id_re;_FIND_VERSION_TWEAK|&id_re;_FIND_VERSION_PATCH|&id_re;_FIND_VERSION_MINOR|&id_re;_FIND_VERSION_MAJOR|&id_re;_FIND_VERSION_EXACT|&id_re;_FIND_VERSION_COUNT|&id_re;_FIND_VERSION|&id_re;_FIND_REQUIRED_&id_re;|&id_re;_FIND_REQUIRED|&id_re;_FIND_QUIETLY|&id_re;_FIND_COMPONENTS|&id_re;_DESCRIPTION|&id_re;_CONSIDERED_VERSIONS|&id_re;_CONSIDERED_CONFIGS|&id_re;_BINARY_DIR)\b" />
+ <RegExpr attribute="Builtin Variable" context="#stay" String="\b(?:SWIG_MODULE_&id_re;_EXTRA_DEPS|ExternalData_URL_ALGO_&id_re;_&id_re;|ExternalData_CUSTOM_SCRIPT_&id_re;|DOXYGEN_&id_re;|CPACK_WIX_PROPERTY_&id_re;|CPACK_WIX_&id_re;_EXTRA_FLAGS|CPACK_WIX_&id_re;_EXTENSIONS|CPACK_RPM_NO_&id_re;_INSTALL_PREFIX_RELOCATION|CPACK_RPM_&id_re;_USER_FILELIST|CPACK_RPM_&id_re;_USER_BINARY_SPECFILE|CPACK_RPM_&id_re;_PACKAGE_URL|CPACK_RPM_&id_re;_PACKAGE_SUMMARY|CPACK_RPM_&id_re;_PACKAGE_SUGGESTS|CPACK_RPM_&id_re;_PACKAGE_REQUIRES_PREUN|CPACK_RPM_&id_re;_PACKAGE_REQUIRES_PRE|CPACK_RPM_&id_re;_PACKAGE_REQUIRES_POSTUN|CPACK_RPM_&id_re;_PACKAGE_REQUIRES_POST|CPACK_RPM_&id_re;_PACKAGE_REQUIRES|CPACK_RPM_&id_re;_PACKAGE_PROVIDES|CPACK_RPM_&id_re;_PACKAGE_PREFIX|CPACK_RPM_&id_re;_PACKAGE_OBSOLETES|CPACK_RPM_&id_re;_PACKAGE_NAME|CPACK_RPM_&id_re;_PACKAGE_GROUP|CPACK_RPM_&id_re;_PACKAGE_DESCRIPTION|CPACK_RPM_&id_re;_PACKAGE_CONFLICTS|CPACK_RPM_&id_re;_PACKAGE_AUTOREQPROV|CPACK_RPM_&id_re;_PACKAGE_AUTOREQ|CPACK_RPM_&id_re;_PACKAGE_AUTOPROV|CPACK_RPM_&id_re;_PACKAGE_ARCHITECTURE|CPACK_RPM_&id_re;_FILE_NAME|CPACK_RPM_&id_re;_DEFAULT_USER|CPACK_RPM_&id_re;_DEFAULT_GROUP|CPACK_RPM_&id_re;_DEFAULT_FILE_PERMISSIONS|CPACK_RPM_&id_re;_DEFAULT_DIR_PERMISSIONS|CPACK_RPM_&id_re;_DEBUGINFO_PACKAGE|CPACK_RPM_&id_re;_DEBUGINFO_FILE_NAME|CPACK_RPM_&id_re;_BUILD_SOURCE_DIRS_PREFIX|CPACK_PREFLIGHT_&id_re;_SCRIPT|CPACK_POSTFLIGHT_&id_re;_SCRIPT|CPACK_NUGET_PACKAGE_DEPENDENCIES_&id_re;_VERSION|CPACK_NUGET_&id_re;_PACKAGE_VERSION|CPACK_NUGET_&id_re;_PACKAGE_TITLE|CPACK_NUGET_&id_re;_PACKAGE_TAGS|CPACK_NUGET_&id_re;_PACKAGE_RELEASE_NOTES|CPACK_NUGET_&id_re;_PACKAGE_OWNERS|CPACK_NUGET_&id_re;_PACKAGE_NAME|CPACK_NUGET_&id_re;_PACKAGE_LICENSE_FILE_NAME|CPACK_NUGET_&id_re;_PACKAGE_LICENSE_EXPRESSION|CPACK_NUGET_&id_re;_PACKAGE_LICENSEURL|CPACK_NUGET_&id_re;_PACKAGE_LANGUAGE|CPACK_NUGET_&id_re;_PACKAGE_ICONURL|CPACK_NUGET_&id_re;_PACKAGE_ICON|CPACK_NUGET_&id_re;_PACKAGE_HOMEPAGE_URL|CPACK_NUGET_&id_re;_PACKAGE_DESCRIPTION_SUMMARY|CPACK_NUGET_&id_re;_PACKAGE_DESCRIPTION|CPACK_NUGET_&id_re;_PACKAGE_DEPENDENCIES_&id_re;_VERSION|CPACK_NUGET_&id_re;_PACKAGE_DEPENDENCIES|CPACK_NUGET_&id_re;_PACKAGE_COPYRIGHT|CPACK_NUGET_&id_re;_PACKAGE_AUTHORS|CPACK_NSIS_&id_re;_INSTALL_DIRECTORY|CPACK_DMG_&id_re;_FILE_NAME|CPACK_DEBIAN_&id_re;_PACKAGE_SUGGESTS|CPACK_DEBIAN_&id_re;_PACKAGE_SOURCE|CPACK_DEBIAN_&id_re;_PACKAGE_SHLIBDEPS|CPACK_DEBIAN_&id_re;_PACKAGE_SECTION|CPACK_DEBIAN_&id_re;_PACKAGE_REPLACES|CPACK_DEBIAN_&id_re;_PACKAGE_RECOMMENDS|CPACK_DEBIAN_&id_re;_PACKAGE_PROVIDES|CPACK_DEBIAN_&id_re;_PACKAGE_PRIORITY|CPACK_DEBIAN_&id_re;_PACKAGE_PREDEPENDS|CPACK_DEBIAN_&id_re;_PACKAGE_NAME|CPACK_DEBIAN_&id_re;_PACKAGE_ENHANCES|CPACK_DEBIAN_&id_re;_PACKAGE_DEPENDS|CPACK_DEBIAN_&id_re;_PACKAGE_CONTROL_STRICT_PERMISSION|CPACK_DEBIAN_&id_re;_PACKAGE_CONTROL_EXTRA|CPACK_DEBIAN_&id_re;_PACKAGE_CONFLICTS|CPACK_DEBIAN_&id_re;_PACKAGE_BREAKS|CPACK_DEBIAN_&id_re;_PACKAGE_ARCHITECTURE|CPACK_DEBIAN_&id_re;_FILE_NAME|CPACK_DEBIAN_&id_re;_DESCRIPTION|CPACK_DEBIAN_&id_re;_DEBUGINFO_PACKAGE|CPACK_COMPONENT_&id_re;_REQUIRED|CPACK_COMPONENT_&id_re;_HIDDEN|CPACK_COMPONENT_&id_re;_GROUP|CPACK_COMPONENT_&id_re;_DISPLAY_NAME|CPACK_COMPONENT_&id_re;_DISABLED|CPACK_COMPONENT_&id_re;_DESCRIPTION|CPACK_COMPONENT_&id_re;_DEPENDS|CPACK_BINARY_&id_re;|CPACK_ARCHIVE_&id_re;_FILE_NAME|CPACK_&id_re;_COMPONENT_INSTALL|CMAKE_XCODE_ATTRIBUTE_&id_re;|CMAKE_USER_MAKE_RULES_OVERRIDE_&id_re;|CMAKE_STATIC_LINKER_FLAGS_&id_re;_INIT|CMAKE_STATIC_LINKER_FLAGS_&id_re;|CMAKE_SHARED_LINKER_FLAGS_&id_re;_INIT|CMAKE_SHARED_LINKER_FLAGS_&id_re;|CMAKE_RUNTIME_OUTPUT_DIRECTORY_&id_re;|CMAKE_PROJECT_&id_re;_INCLUDE|CMAKE_POLICY_WARNING_CMP[0-9]{4}|CMAKE_POLICY_DEFAULT_CMP[0-9]{4}|CMAKE_PDB_OUTPUT_DIRECTORY_&id_re;|CMAKE_MODULE_LINKER_FLAGS_&id_re;_INIT|CMAKE_MODULE_LINKER_FLAGS_&id_re;|CMAKE_MATCH_[0-9]+|CMAKE_MAP_IMPORTED_CONFIG_&id_re;|CMAKE_LIBRARY_OUTPUT_DIRECTORY_&id_re;|CMAKE_INTERPROCEDURAL_OPTIMIZATION_&id_re;|CMAKE_FRAMEWORK_MULTI_CONFIG_POSTFIX_&id_re;|CMAKE_EXE_LINKER_FLAGS_&id_re;_INIT|CMAKE_EXE_LINKER_FLAGS_&id_re;|CMAKE_DISABLE_FIND_PACKAGE_&id_re;|CMAKE_COMPILE_PDB_OUTPUT_DIRECTORY_&id_re;|CMAKE_ARGV[0-9]+|CMAKE_ARCHIVE_OUTPUT_DIRECTORY_&id_re;|CMAKE_&id_re;_VISIBILITY_PRESET|CMAKE_&id_re;_STANDARD_LIBRARIES|CMAKE_&id_re;_STANDARD_INCLUDE_DIRECTORIES|CMAKE_&id_re;_SOURCE_FILE_EXTENSIONS|CMAKE_&id_re;_SIZEOF_DATA_PTR|CMAKE_&id_re;_SIMULATE_VERSION|CMAKE_&id_re;_SIMULATE_ID|CMAKE_&id_re;_POSTFIX|CMAKE_&id_re;_OUTPUT_EXTENSION|CMAKE_&id_re;_LINK_LIBRARY_FLAG|CMAKE_&id_re;_LINK_LIBRARY_FILE_FLAG|CMAKE_&id_re;_LINK_EXECUTABLE|CMAKE_&id_re;_LINKER_WRAPPER_FLAG_SEP|CMAKE_&id_re;_LINKER_WRAPPER_FLAG|CMAKE_&id_re;_LINKER_PREFERENCE_PROPAGATES|CMAKE_&id_re;_LINKER_PREFERENCE|CMAKE_&id_re;_LINKER_LAUNCHER|CMAKE_&id_re;_LIBRARY_ARCHITECTURE|CMAKE_&id_re;_INCLUDE_WHAT_YOU_USE|CMAKE_&id_re;_IMPLICIT_LINK_LIBRARIES|CMAKE_&id_re;_IMPLICIT_LINK_FRAMEWORK_DIRECTORIES|CMAKE_&id_re;_IMPLICIT_LINK_DIRECTORIES|CMAKE_&id_re;_IMPLICIT_INCLUDE_DIRECTORIES|CMAKE_&id_re;_IGNORE_EXTENSIONS|CMAKE_&id_re;_GHS_KERNEL_FLAGS_RELWITHDEBINFO|CMAKE_&id_re;_GHS_KERNEL_FLAGS_RELEASE|CMAKE_&id_re;_GHS_KERNEL_FLAGS_MINSIZEREL|CMAKE_&id_re;_GHS_KERNEL_FLAGS_DEBUG|CMAKE_&id_re;_FLAGS_RELWITHDEBINFO_INIT|CMAKE_&id_re;_FLAGS_RELWITHDEBINFO|CMAKE_&id_re;_FLAGS_RELEASE_INIT|CMAKE_&id_re;_FLAGS_RELEASE|CMAKE_&id_re;_FLAGS_MINSIZEREL_INIT|CMAKE_&id_re;_FLAGS_MINSIZEREL|CMAKE_&id_re;_FLAGS_INIT|CMAKE_&id_re;_FLAGS_DEBUG_INIT|CMAKE_&id_re;_FLAGS_DEBUG|CMAKE_&id_re;_FLAGS|CMAKE_&id_re;_CREATE_STATIC_LIBRARY|CMAKE_&id_re;_CREATE_SHARED_MODULE|CMAKE_&id_re;_CREATE_SHARED_LIBRARY|CMAKE_&id_re;_CPPLINT|CMAKE_&id_re;_CPPCHECK|CMAKE_&id_re;_COMPILE_OBJECT|CMAKE_&id_re;_COMPILER_VERSION|CMAKE_&id_re;_COMPILER_TARGET|CMAKE_&id_re;_COMPILER_RANLIB|CMAKE_&id_re;_COMPILER_LOADED|CMAKE_&id_re;_COMPILER_LAUNCHER|CMAKE_&id_re;_COMPILER_ID|CMAKE_&id_re;_COMPILER_EXTERNAL_TOOLCHAIN|CMAKE_&id_re;_COMPILER_AR|CMAKE_&id_re;_COMPILER|CMAKE_&id_re;_CLANG_TIDY|CMAKE_&id_re;_BYTE_ORDER|CMAKE_&id_re;_ARCHIVE_FINISH|CMAKE_&id_re;_ARCHIVE_CREATE|CMAKE_&id_re;_ARCHIVE_APPEND|CMAKE_&id_re;_ANDROID_TOOLCHAIN_SUFFIX|CMAKE_&id_re;_ANDROID_TOOLCHAIN_PREFIX|CMAKE_&id_re;_ANDROID_TOOLCHAIN_MACHINE|ARGV[0-9]+|&id_re;__TRYRUN_OUTPUT|&id_re;_VERSION_TWEAK|&id_re;_VERSION_STRING|&id_re;_VERSION_PATCH|&id_re;_VERSION_MINOR|&id_re;_VERSION_MAJOR|&id_re;_VERSION_COUNT|&id_re;_VERSION|&id_re;_UNPARSED_ARGUMENTS|&id_re;_SOURCE_DIR|&id_re;_ROOT|&id_re;_MODULE_NAME|&id_re;_LIBRARY_DIRS|&id_re;_LIBRARIES|&id_re;_KEYWORDS_MISSING_VALUES|&id_re;_IS_TOP_LEVEL|&id_re;_INCLUDE_DIRS|&id_re;_HOMEPAGE_URL|&id_re;_FOUND|&id_re;_FIND_VERSION_RANGE_MIN|&id_re;_FIND_VERSION_RANGE_MAX|&id_re;_FIND_VERSION_RANGE|&id_re;_FIND_VERSION_MIN_TWEAK|&id_re;_FIND_VERSION_MIN_PATCH|&id_re;_FIND_VERSION_MIN_MINOR|&id_re;_FIND_VERSION_MIN_MAJOR|&id_re;_FIND_VERSION_MIN_COUNT|&id_re;_FIND_VERSION_MIN|&id_re;_FIND_VERSION_MAX_TWEAK|&id_re;_FIND_VERSION_MAX_PATCH|&id_re;_FIND_VERSION_MAX_MINOR|&id_re;_FIND_VERSION_MAX_MAJOR|&id_re;_FIND_VERSION_MAX_COUNT|&id_re;_FIND_VERSION_MAX|&id_re;_FIND_VERSION_EXACT|&id_re;_FIND_VERSION_COUNT|&id_re;_FIND_VERSION_COMPLETE|&id_re;_FIND_REQUIRED_&id_re;|&id_re;_FIND_REQUIRED|&id_re;_FIND_QUIETLY|&id_re;_FIND_COMPONENTS|&id_re;_DESCRIPTION|&id_re;_CONSIDERED_VERSIONS|&id_re;_CONSIDERED_CONFIGS|&id_re;_CONFIG|&id_re;_BINARY_DIR)\b" />
</context>
<context attribute="Normal Text" lineEndContext="#stay" name="Detect Variable Substitutions">
diff --git a/src/libs/3rdparty/syntax-highlighting/data/syntax/doxygen.xml b/src/libs/3rdparty/syntax-highlighting/data/syntax/doxygen.xml
index d7a53a167c..5516c1454b 100644
--- a/src/libs/3rdparty/syntax-highlighting/data/syntax/doxygen.xml
+++ b/src/libs/3rdparty/syntax-highlighting/data/syntax/doxygen.xml
@@ -1,12 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE language SYSTEM "language.dtd"
[
- <!ENTITY wordsep "(?:[][,?;()]|\.$|\.?\s)"> <!-- things that end a TagWord -->
+ <!ENTITY wordsep "(?:[][,?;()]|\.$|\.?\s|$)"> <!-- things that end a TagWord -->
<!ENTITY sl_word ".*?(?=&wordsep;)">
<!ENTITY ml_word ".*?(?=&wordsep;|\*/)">
]>
<language name="Doxygen"
- version="13"
+ version="14"
kateversion="5.0"
section="Markup"
extensions="*.dox;*.doxygen"
diff --git a/src/libs/3rdparty/syntax-highlighting/data/syntax/ini.xml b/src/libs/3rdparty/syntax-highlighting/data/syntax/ini.xml
index 8b36a56290..476522961b 100644
--- a/src/libs/3rdparty/syntax-highlighting/data/syntax/ini.xml
+++ b/src/libs/3rdparty/syntax-highlighting/data/syntax/ini.xml
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE language SYSTEM "language.dtd">
-<language name="INI Files" section="Configuration" extensions="*.ini;*.pls;*.kcfgc" mimetype="" version="8" kateversion="5.0" author="Jan Janssen (medhefgo@web.de)" license="LGPL">
+<language name="INI Files" section="Configuration" extensions="*.ini;*.pls;*.kcfgc" mimetype="" version="10" kateversion="5.0" author="Jan Janssen (medhefgo@web.de)" license="LGPL">
<highlighting>
<list name="keywords">
@@ -34,15 +34,26 @@
<contexts>
<context name="ini" attribute="Normal Text" lineEndContext="#stay">
- <RangeDetect attribute="Section" context="#stay" char="[" char1="]" beginRegion="Section" endRegion="Section" />
+ <RangeDetect attribute="Section" context="#stay" char="[" char1="]" beginRegion="Section" endRegion="Section" />
<DetectChar attribute="Assignment" context="Value" char="=" />
<AnyChar String=";#" attribute="Comment" context="Comment" firstNonSpace="true" />
+ <DetectIdentifier />
+ <DetectSpaces />
+ </context>
+
+ <context name="Value" attribute="Value" lineEndContext="#pop" fallthrough="1" fallthroughContext="#pop!NormalValue">
+ <RegExpr context="#pop!SpecialValue" String="\s*((-?(\d+(\.\d*)?|\.d+)(e\d+)?|On|Off|Defaults?|Localhost|Null|True|False|Yes|No|Normal)\s*$|~?(E_ALL|E_ERROR|E_WARNING|E_PARSE|E_NOTICE|E_STRICT|E_CORE_ERROR|E_CORE_WARNING|E_COMPILE_ERROR|E_COMPILE_WARNING|E_USER_ERROR|E_USER_WARNING|E_USER_NOTICE)\b)" lookAhead="1" insensitive="1"/>
</context>
- <context name="Value" attribute="Value" lineEndContext="#pop" >
+ <context name="SpecialValue" attribute="Value" lineEndContext="#pop">
<Float attribute="Float" />
<Int attribute="Int" />
- <keyword attribute="Keyword" String="keywords" />
+ <keyword attribute="Keyword" String="keywords"/>
+ <DetectChar attribute="Int" char="-" />
+ <DetectSpaces />
+ </context>
+
+ <context name="NormalValue" attribute="Value" lineEndContext="#pop">
</context>
<context name="Comment" attribute="Comment" lineEndContext="#pop">
diff --git a/src/libs/3rdparty/syntax-highlighting/data/syntax/java.xml b/src/libs/3rdparty/syntax-highlighting/data/syntax/java.xml
index 6091cd4ee2..e71b1618a0 100644
--- a/src/libs/3rdparty/syntax-highlighting/data/syntax/java.xml
+++ b/src/libs/3rdparty/syntax-highlighting/data/syntax/java.xml
@@ -7,7 +7,7 @@
<!ENTITY float "(\b&int;(\.((&int;&exp;?+|&exp;)[fFdD]?\b|[fFdD]\b)?|&exp;[fFdD]?\b|[fFdD]\b)|\.&int;&exp;?[fFdD]?\b)">
<!ENTITY hexfloat "\b0[xX](&hex;\.?+&hex;?+|\.&hex;?)[pP][-+]?&int;[fFdD]?\b">
]>
-<language name="Java" version="9" kateversion="5.62" section="Sources" extensions="*.java" mimetype="text/x-java" license="LGPL" author="Alfredo Luiz Foltran Fialho (alfoltran@ig.com.br)">
+<language name="Java" version="10" kateversion="5.62" section="Sources" extensions="*.java" mimetype="text/x-java" license="LGPL" author="Alfredo Luiz Foltran Fialho (alfoltran@ig.com.br)">
<highlighting>
<list name="java15">
<item>ACTIVE</item>
@@ -3732,6 +3732,7 @@
<item>volatile</item>
</list>
<list name="control flow">
+ <item>assert</item>
<item>break</item>
<item>case</item>
<item>catch</item>
@@ -3760,6 +3761,7 @@
<item>long</item>
<item>short</item>
<item>static</item>
+ <item>var</item>
<item>void</item>
</list>
<contexts>
diff --git a/src/libs/3rdparty/syntax-highlighting/data/syntax/markdown.xml b/src/libs/3rdparty/syntax-highlighting/data/syntax/markdown.xml
index b35397af9c..f03587977a 100644
--- a/src/libs/3rdparty/syntax-highlighting/data/syntax/markdown.xml
+++ b/src/libs/3rdparty/syntax-highlighting/data/syntax/markdown.xml
@@ -90,7 +90,7 @@
<!ENTITY checkbox "\[[ x]\](?=\s)">
]>
-<language name="Markdown" version="17" kateversion="5.79" section="Markup" extensions="*.md;*.mmd;*.markdown" priority="15" author="Darrin Yeager, Claes Holmerson" license="GPL,BSD">
+<language name="Markdown" version="19" kateversion="5.79" section="Markup" extensions="*.md;*.mmd;*.markdown" priority="15" author="Darrin Yeager, Claes Holmerson" license="GPL,BSD">
<highlighting>
<contexts>
<!-- Start of the Markdown document: find metadata or code block -->
@@ -149,14 +149,33 @@
</context>
<context name="find-header" attribute="Normal Text" lineEndContext="#pop">
- <RegExpr attribute="Header H1" context="#pop" String="^#\s.*[#]?$" column="0"/>
- <RegExpr attribute="Header H2" context="#pop" String="^##\s.*[#]?$" column="0"/>
- <RegExpr attribute="Header H3" context="#pop" String="^###\s.*[#]?$" column="0"/>
- <RegExpr attribute="Header H4" context="#pop" String="^####\s.*[#]?$" column="0"/>
- <RegExpr attribute="Header H5" context="#pop" String="^#####\s.*[#]?$" column="0"/>
- <RegExpr attribute="Header H6" context="#pop" String="^######\s.*[#]?$" column="0"/>
+ <!-- TODO: Replace "(?=.$)" in the regexes with just "$" when close-H#-region are removed -->
+ <RegExpr attribute="Header H1" context="#pop!close-H2-region" String="^#\s.*[#]?(?=.$)" column="0" endRegion="H1" beginRegion="H1"/>
+ <RegExpr attribute="Header H2" context="#pop!close-H3-region" String="^##\s.*[#]?(?=.$)" column="0" endRegion="H2" beginRegion="H2"/>
+ <RegExpr attribute="Header H3" context="#pop!close-H4-region" String="^###\s.*[#]?(?=.$)" column="0" endRegion="H3" beginRegion="H3"/>
+ <RegExpr attribute="Header H4" context="#pop!close-H5-region" String="^####\s.*[#]?(?=.$)" column="0" endRegion="H4" beginRegion="H4"/>
+ <RegExpr attribute="Header H5" context="#pop!close-H6-region" String="^#####\s.*[#]?(?=.$)" column="0" endRegion="H5" beginRegion="H5"/>
+ <RegExpr attribute="Header H6" context="#pop" String="^######\s.*[#]?$" column="0" endRegion="H6" beginRegion="H6"/>
<DetectChar attribute="Normal Text" context="#pop" char="#"/>
</context>
+ <!-- BUG: 441278 sub-headers should be closed when their parent header is closed (e.g. in h1 h2 h3 h1, h1-h3 should all be closed at the 2nd h1) -->
+ <!-- TODO: Port to a less hacky version (maybe a new attribute for declaring multiple endRegions) -->
+ <context name="close-H2-region" attribute="Header H2" lineEndContext="#pop!close-H3-region" fallthroughContext="#pop!close-H3-region">
+ <RegExpr attribute="Header H2" context="#pop!close-H3-region" String="." lookAhead="true" endRegion="H2"/>
+ </context>
+ <context name="close-H3-region" attribute="Header H3" lineEndContext="#pop!close-H4-region" fallthroughContext="#pop!close-H4-region">
+ <RegExpr attribute="Header H3" context="#pop!close-H4-region" String="." lookAhead="true" endRegion="H3"/>
+ </context>
+ <context name="close-H4-region" attribute="Header H4" lineEndContext="#pop!close-H5-region" fallthroughContext="#pop!close-H5-region">
+ <RegExpr attribute="Header H4" context="#pop!close-H5-region" String="." lookAhead="true" endRegion="H4"/>
+ </context>
+ <context name="close-H5-region" attribute="Header H5" lineEndContext="#pop!close-H6-region" fallthroughContext="#pop!close-H6-region">
+ <RegExpr attribute="Header H5" context="#pop!close-H6-region" String="." lookAhead="true" endRegion="H5"/>
+ </context>
+ <context name="close-H6-region" attribute="Header H6" lineEndContext="#pop" fallthroughContext="#pop">
+ <RegExpr attribute="Header H6" context="#pop" String="." endRegion="H6"/>
+ </context>
+
<context name="find-strong-normal" attribute="Normal Text" lineEndContext="#pop">
<RegExpr attribute="Strong-Emphasis Text" context="#pop" minimal="true" String="&strongemphasisregex_ast_und;|&strongemphasisregex_ast_und2;"/>
<RegExpr attribute="Strong Text" context="#pop" minimal="true" String="&strongregex_ast;"/>
diff --git a/src/libs/3rdparty/syntax-highlighting/data/syntax/perl.xml b/src/libs/3rdparty/syntax-highlighting/data/syntax/perl.xml
index fdf2266558..c9a60d64db 100644
--- a/src/libs/3rdparty/syntax-highlighting/data/syntax/perl.xml
+++ b/src/libs/3rdparty/syntax-highlighting/data/syntax/perl.xml
@@ -39,7 +39,7 @@
Enhance tr/// and y/// support.
-->
-<language name="Perl" version="17" kateversion="5.0" section="Scripts" extensions="*.pl;*.PL;*.pm" mimetype="application/x-perl;text/x-perl" priority="5" author="Anders Lund (anders@alweb.dk)" license="LGPLv2">
+<language name="Perl" version="18" kateversion="5.0" section="Scripts" extensions="*.pl;*.PL;*.pm" mimetype="application/x-perl;text/x-perl" priority="5" author="Anders Lund (anders@alweb.dk)" license="LGPLv2">
<highlighting>
<list name="keywords">
<item>if</item>
@@ -92,7 +92,7 @@
<item>+</item>
<item>-</item>
<item>*</item>
- <!-- <item>/</item>//-->
+ <!-- <item>/</item>//-->
<item>%</item>
<item>||</item>
<item>//</item>
@@ -420,7 +420,8 @@
<DetectChar attribute="Operator" context="quote_word_paren" char="(" beginRegion="Wordlist" />
<DetectChar attribute="Operator" context="quote_word_brace" char="{" beginRegion="Wordlist" />
<DetectChar attribute="Operator" context="quote_word_bracket" char="[" beginRegion="Wordlist" />
- <RegExpr attribute="Operator" context="quote_word" String="([^a-zA-Z0-9_\s[\]{}()])" beginRegion="Wordlist" />
+ <DetectChar attribute="Operator" context="quote_word_angular" char="&lt;" beginRegion="Wordlist" />
+ <RegExpr attribute="Operator" context="quote_word" String="([^a-zA-Z0-9_\s[\]{}()\&lt;&gt;])" beginRegion="Wordlist" />
<RegExpr attribute="Comment" context="#stay" String="\s+#.*" /><!-- q[qwx] # == comment, look for the delim on the next line -->
</context>
@@ -756,6 +757,12 @@
<Detect2Chars attribute="Normal Text" context="#stay" char="\" char1="]" />
<DetectChar attribute="Operator" context="#pop#pop#pop" char="]" endRegion="Wordlist" />
</context>
+ <context name="quote_word_angular" attribute="Normal Text" lineEndContext="#stay">
+ <DetectSpaces />
+ <DetectIdentifier />
+ <Detect2Chars attribute="Normal Text" context="#stay" char="\" char1="&gt;" />
+ <DetectChar attribute="Operator" context="#pop#pop#pop" char="&gt;" endRegion="Wordlist" />
+ </context>
<!-- ====== Here Documents ====== -->
<context name="find_here_document" attribute="Normal Text" lineEndContext="#pop" >
diff --git a/src/libs/3rdparty/syntax-highlighting/data/syntax/python.xml b/src/libs/3rdparty/syntax-highlighting/data/syntax/python.xml
index f1c89a54e4..676872f03f 100644
--- a/src/libs/3rdparty/syntax-highlighting/data/syntax/python.xml
+++ b/src/libs/3rdparty/syntax-highlighting/data/syntax/python.xml
@@ -33,6 +33,10 @@
type ::= "b" | "c" | "d" | "e" | "E" | "f" | "F" | "g" | "G" | "n" | "o" | "s" | "x" | "X" | "%"
-->
<!ENTITY strsubstitution_py3 "\{(?:(?:[a-zA-Z0-9_]+|[0-9]+)(?:\.[a-zA-Z0-9_]+|\[[^ \]]+\])*)?(?:![rs])?(?::(?:[^}]?[&lt;&gt;=^])?[ +-]?#?0?[0-9]*(?:\.[0-9]+)?[bcdeEfFgGnosxX&#37;]?)?\}">
+
+ <!ENTITY rawString "(?:ru|u?r|)(?:'(?:[^']++|\\')*+'|&quot;(?:[^&quot;]++|\\&quot;)*+&quot;)">
+ <!ENTITY formatString "(?:r?f|fr?)(?:'(?:[^'{]++|\\'|\{\{|\{[^}]++\})*+'|&quot;(?:[^&quot;]++|\\&quot;|\{\{|\{[^}]*+\})*+&quot;)">
+ <!ENTITY string "&rawString;|&formatString;">
]>
<!-- Python syntax highlightning v0.9 by Per Wigren -->
<!-- Python syntax highlighting v1.9 by Michael Bueker (improved keyword differentiation) -->
@@ -48,7 +52,7 @@
<!-- v2.07 add support for %prog and co, see bug 142832 -->
<!-- v2.08 add missing overloaders, new Python 3 statements, builtins, and keywords -->
<!-- v2.29 recognize escape sequenzes correctly -->
-<language name="Python" version="14" style="python" indenter="python" kateversion="5.0" section="Scripts" extensions="*.py;*.pyw;SConstruct;SConscript;*.FCMacro" mimetype="application/x-python;text/x-python;text/x-python3" casesensitive="1" author="Michael Bueker" license="">
+<language name="Python" version="22" style="python" indenter="python" kateversion="5.0" section="Scripts" extensions="*.py;*.pyw;SConstruct;SConscript;*.FCMacro" mimetype="application/x-python;text/x-python;text/x-python3" casesensitive="1" author="Michael Bueker" license="">
<highlighting>
<list name="import">
<item>import</item>
@@ -86,10 +90,21 @@
<item>try</item>
<item>while</item>
<item>with</item>
- <item>yield</item>
<item>async</item>
<item>await</item>
</list>
+ <list name="flow_yield">
+ <item>yield</item>
+ <!--
+ "yield from" added here as a keyword for autocompletion. The actual handling
+ is in context="yield" so that we won't need to add space as a weakDeliminator.
+ -->
+ <item>yield from</item>
+ </list>
+ <list name="patternmatching">
+ <item>match</item>
+ <item>case</item>
+ </list>
<list name="builtinfuncs">
<item>__import__</item>
<item>abs</item>
@@ -366,89 +381,137 @@
</list>
<contexts>
<context name="Normal" attribute="Normal Text" lineEndContext="#stay">
+ <DetectSpaces attribute="Normal Text"/>
+
<keyword attribute="Import" String="import" context="#stay"/>
<keyword attribute="Definition Keyword" String="defs" context="#stay"/>
<keyword attribute="Operator Keyword" String="operators" context="#stay"/>
<keyword attribute="Flow Control Keyword" String="flow" context="#stay"/>
+ <keyword attribute="Flow Control Keyword" String="flow_yield" context="yield"/>
+ <keyword attribute="Flow Control Keyword" String="patternmatching" context="Pattern Matching" lookAhead="1" firstNonSpace="1"/>
<keyword attribute="Builtin Function" String="builtinfuncs" context="#stay"/>
<keyword attribute="Special Variable" String="specialvars" context="#stay"/>
<keyword attribute="Extensions" String="bindings" context="#stay"/>
<keyword attribute="Exceptions" String="exceptions" context="#stay"/>
<keyword attribute="Overloaders" String="overloaders" context="#stay"/>
- <RegExpr attribute="Normal Text" String="[a-zA-Z_][a-zA-Z_0-9]{2,}" context="#stay"/>
-
- <!-- Complex: 1j ; 1.1j ; 1.j ; .1j ; 1e3j ; 1.1e3j ; 1.e3j ; .1e3j -->
- <RegExpr attribute="Complex" String="(?:&beforeDigit;&digitPart;(?:\.(?:&digitPart;)?)?|&beforePointFloat;\.&digitPart;)(?:[eE][\+\-]?&digitPart;)?[jJ]\b" context="#stay"/>
- <!-- Hexadecimal: 0xA1, Binary: 0b01, Octal: 0o71 -->
- <RegExpr attribute="Hex" String="&beforeDigit;0[xX](?:_?[\da-fA-F])+\b" context="#stay"/>
- <RegExpr attribute="Binary" String="&beforeDigit;0[bB](?:_?[01])+\b" context="#stay"/>
- <RegExpr attribute="Octal" String="&beforeDigit;0[oO](?:_?[0-7])+\b" context="#stay"/>
- <!-- Float: 1.1 ; 1. ; .1 ; 1e3 ; 1.1e3 ; 1.e3 ; .1e3 -->
- <RegExpr attribute="Float" String="(?:&beforeDigit;&digitPart;(?:\.(?:&digitPart;)?)?|&beforePointFloat;\.&digitPart;)[eE][\+\-]?&digitPart;\b|(?:&beforeDigit;&digitPart;\.(?:&digitPart;\b)?|&beforePointFloat;\.&digitPart;\b)" context="#stay"/>
- <!-- Decimal: 123 ; 000 -->
- <RegExpr attribute="Int" String="&beforeDigit;(?:[1-9](?:_?\d)*|0(?:_?0)*)[lL]?\b" context="#stay"/>
<DetectChar attribute="Normal Text" char="{" context="Dictionary" beginRegion="Dictionary"/>
<DetectChar attribute="Normal Text" char="[" context="List" beginRegion="List"/>
<DetectChar attribute="Normal Text" char="(" context="Tuple" beginRegion="Tuple"/>
- <IncludeRules context="CommentVariants" />
-
<DetectChar attribute="Comment" char="#" context="Hash comment"/>
+ <IncludeRules context="Number" />
+ <IncludeRules context="CommentVariants" />
<IncludeRules context="StringVariants" />
+ <DetectIdentifier attribute="Normal Text"/>
+
<RegExpr attribute="Decorator" String="@[_a-zA-Z[:^ascii:]][\._a-zA-Z0-9[:^ascii:]]*" firstNonSpace="true"/>
- <AnyChar attribute="Operator" String="+*/%\|=;\!&lt;&gt;!^&amp;~-@" context="#stay"/>
+ <AnyChar attribute="Operator" String="+*/%\|=;&lt;&gt;!^&amp;~-@" context="#stay"/>
+
+ <Int attribute="Error"/>
+ </context>
+
+ <!-- https://docs.python.org/2/reference/lexical_analysis.html#integer-and-long-integer-literals -->
+ <!-- https://docs.python.org/3/reference/lexical_analysis.html#integer-literals -->
+ <context name="Number" attribute="Normal Text" lineEndContext="#pop">
+ <!-- fast path -->
+ <RegExpr String="&beforeDigit;[0-9]|&beforePointFloat;\.[0-9]" context="AssumeNumber" lookAhead="1"/>
+ </context>
+ <context name="AssumeNumber" attribute="Normal Text" lineEndContext="#pop">
+ <!-- Complex: 1j ; 1.1j ; 1.j ; .1j ; 1e3j ; 1.1e3j ; 1.e3j ; .1e3j -->
+ <RegExpr attribute="Complex" String="(?:&digitPart;(?:\.(?:&digitPart;)?)?|&beforePointFloat;\.&digitPart;)(?:[eE][\+\-]?&digitPart;)?[jJ]" context="CheckSuffixError"/>
+ <!-- Hexadecimal: 0xA1, Binary: 0b01, Octal: 0o71 -->
+ <RegExpr attribute="Hex" String="0[xX](?:_?[0-9a-fA-F])+" context="CheckSuffixError"/>
+ <RegExpr attribute="Binary" String="0[bB](?:_?[01])+" context="CheckSuffixError"/>
+ <RegExpr attribute="Octal" String="0[oO](?:_?[0-7])+" context="CheckSuffixError"/>
+ <!-- Float: 1.1 ; 1. ; .1 ; 1e3 ; 1.1e3 ; 1.e3 ; .1e3 -->
+ <RegExpr attribute="Float" String="(?:&digitPart;(?:\.(?:&digitPart;)?)?|\.&digitPart;)[eE][\+\-]?&digitPart;|&digitPart;\.(?:&digitPart;)?|\.&digitPart;" context="CheckSuffixError"/>
+ <!-- Decimal: 123 ; 000 -->
+ <!-- l and L are python2 suffixes -->
+ <RegExpr attribute="Int" String="(?:[1-9](?:_?\d)*|0(?:_?0)*)[lL]?" context="CheckSuffixError"/>
+ </context>
+ <context name="CheckSuffixError" attribute="Normal Text" lineEndContext="#pop#pop" fallthrough="1" fallthroughContext="#pop#pop">
+ <RegExpr attribute="Error" String="[\w\d]+" context="#pop#pop"/>
+ </context>
+
+ <context name="yield" attribute="Flow Control Keyword" lineEndContext="#pop" fallthrough="1" fallthroughContext="#pop">
+ <DetectSpaces attribute="Normal Text" context="#stay"/>
+ <WordDetect attribute="Flow Control Keyword" context="#pop" String="from"/>
+ </context>
+
+ <context name="Pattern Matching" attribute="Flow Control Keyword" lineEndContext="#pop">
+ <!--
+ Python 3.10: https://docs.python.org/3.10/reference/compound_stmts.html#the-match-statement
+ ( 'match' | 'case' ) expression ':'
+ exclude:
+ ( 'match' | 'case' ) ( 'if' | 'for' | '.' | ':' | '=' | ',' | ']' | ')' ) ...
+ -->
+ <RegExpr attribute="Flow Control Keyword" String="\w++(?=\s+(?!(?:if|for)\b)[\w'&quot;~]|\s*+(?![.:=\]),]|(?:if|for)\b)((?:&string;|[^#;(){}]|\(\)|\((?1)\)|\{\}|\{(\s*+(?:(?:&string;|[a-zA-Z0-9.]++)\s*+:\s*+(?:&string;|[^#;(){},]|\(\)|\((?1)\)|\{\}|\{(?2)\})++,?)*+)\})+?):)|" context="#pop"/>
+ <DetectIdentifier attribute="Normal Text" context="#pop"/>
</context>
<context name="#CheckForString" attribute="Normal Text" lineEndContext="#pop" fallthrough="true" fallthroughContext="#pop">
<DetectSpaces/>
- <LineContinue attribute="Normal Text" context="CheckForStringNext"/>
+ <LineContinue attribute="Normal Text" context="#pop!CheckForStringNext"/>
</context>
- <context name="CheckForStringNext" attribute="Normal Text" lineEndContext="#pop" fallthrough="true" fallthroughContext="#pop">
+ <context name="CheckForStringNext" attribute="Normal Text" lineEndContext="#pop#pop" fallthrough="true" fallthroughContext="#pop#pop">
<DetectSpaces/>
- <LineContinue attribute="Normal Text" context="CheckForStringNext"/>
+ <LineContinue attribute="Normal Text" context="#stay"/>
<IncludeRules context="StringVariants"/>
</context>
+ <!-- https://docs.python.org/2/reference/lexical_analysis.html#string-literals -->
+ <!-- https://docs.python.org/3/reference/lexical_analysis.html#string-and-bytes-literals -->
<context name="StringVariants" attribute="Normal Text" lineEndContext="#stay">
- <DetectSpaces/>
-
- <RegExpr attribute="String" String="u?'''" insensitive="true" context="Triple A-string" beginRegion="Triple A-region"/>
- <RegExpr attribute="String" String="u?&quot;&quot;&quot;" insensitive="true" context="Triple Q-string" beginRegion="Triple Q-region"/>
- <RegExpr attribute="String" String="u?'" insensitive="true" context="Single A-string"/>
- <RegExpr attribute="String" String="u?&quot;" insensitive="true" context="Single Q-string"/>
-
- <RegExpr attribute="Raw String" String="(?:u?r|ru)'''" insensitive="true" context="Raw Triple A-string" beginRegion="Triple A-region"/>
- <RegExpr attribute="Raw String" String="(?:u?r|ru)&quot;&quot;&quot;" insensitive="true" context="Raw Triple Q-string" beginRegion="Triple Q-region"/>
- <RegExpr attribute="Raw String" String="(?:u?r|ru)'" insensitive="true" context="Raw A-string"/>
- <RegExpr attribute="Raw String" String="(?:u?r|ru)&quot;" insensitive="true" context="Raw Q-string"/>
-
- <StringDetect attribute="F-String" String="f'''" insensitive="true" context="Triple A-F-String" beginRegion="Triple A-region"/>
- <StringDetect attribute="F-String" String="f&quot;&quot;&quot;" insensitive="true" context="Triple Q-F-String" beginRegion="Triple Q-region"/>
- <StringDetect attribute="F-String" String="f'" insensitive="true" context="Single A-F-String"/>
- <StringDetect attribute="F-String" String="f&quot;" insensitive="true" context="Single Q-F-String"/>
-
- <RegExpr attribute="Raw F-String" String="(?:fr|rf)'''" insensitive="true" context="Raw Triple A-F-String" beginRegion="Triple A-region"/>
- <RegExpr attribute="Raw F-String" String="(?:fr|rf)&quot;&quot;&quot;" insensitive="true" context="Raw Triple Q-F-String" beginRegion="Triple Q-region"/>
- <RegExpr attribute="Raw F-String" String="(?:fr|rf)'" insensitive="true" context="Raw A-F-String"/>
- <RegExpr attribute="Raw F-String" String="(?:fr|rf)&quot;" insensitive="true" context="Raw Q-F-String"/>
- </context>
-
+ <!-- fast path -->
+ <RegExpr String="(?:u|r|b|f|ur|fr|rf|br|rb)?['&quot;]" insensitive="true" context="AssumeStringVariants" lookAhead="1"/>
+ </context>
+ <context name="AssumeStringVariants" attribute="Normal Text" lineEndContext="#stay">
+ <RegExpr attribute="String" String="u?'''" insensitive="true" context="#pop!Triple A-string" beginRegion="Triple A-region"/>
+ <RegExpr attribute="String" String="u?&quot;&quot;&quot;" insensitive="true" context="#pop!Triple Q-string" beginRegion="Triple Q-region"/>
+ <RegExpr attribute="String" String="u?'" insensitive="true" context="#pop!Single A-string"/>
+ <RegExpr attribute="String" String="u?&quot;" insensitive="true" context="#pop!Single Q-string"/>
+
+ <RegExpr attribute="Raw String" String="u?r'''" insensitive="true" context="#pop!Raw Triple A-string" beginRegion="Triple A-region"/>
+ <RegExpr attribute="Raw String" String="u?r&quot;&quot;&quot;" insensitive="true" context="#pop!Raw Triple Q-string" beginRegion="Triple Q-region"/>
+ <RegExpr attribute="Raw String" String="u?r'" insensitive="true" context="#pop!Raw A-string"/>
+ <RegExpr attribute="Raw String" String="u?r&quot;" insensitive="true" context="#pop!Raw Q-string"/>
+
+ <StringDetect attribute="F-String" String="f'''" insensitive="true" context="#pop!Triple A-F-String" beginRegion="Triple A-region"/>
+ <StringDetect attribute="F-String" String="f&quot;&quot;&quot;" insensitive="true" context="#pop!Triple Q-F-String" beginRegion="Triple Q-region"/>
+ <StringDetect attribute="F-String" String="f'" insensitive="true" context="#pop!Single A-F-String"/>
+ <StringDetect attribute="F-String" String="f&quot;" insensitive="true" context="#pop!Single Q-F-String"/>
+
+ <RegExpr attribute="Raw F-String" String="(?:fr|rf)'''" insensitive="true" context="#pop!Raw Triple A-F-String" beginRegion="Triple A-region"/>
+ <RegExpr attribute="Raw F-String" String="(?:fr|rf)&quot;&quot;&quot;" insensitive="true" context="#pop!Raw Triple Q-F-String" beginRegion="Triple Q-region"/>
+ <RegExpr attribute="Raw F-String" String="(?:fr|rf)'" insensitive="true" context="#pop!Raw A-F-String"/>
+ <RegExpr attribute="Raw F-String" String="(?:fr|rf)&quot;" insensitive="true" context="#pop!Raw Q-F-String"/>
+
+ <StringDetect attribute="B-String" String="b'''" insensitive="true" context="#pop!Triple A-B-String" beginRegion="Triple A-region"/>
+ <StringDetect attribute="B-String" String="b&quot;&quot;&quot;" insensitive="true" context="#pop!Triple Q-B-String" beginRegion="Triple Q-region"/>
+ <StringDetect attribute="B-String" String="b'" insensitive="true" context="#pop!Single A-B-String"/>
+ <StringDetect attribute="B-String" String="b&quot;" insensitive="true" context="#pop!Single Q-B-String"/>
+
+ <RegExpr attribute="Raw B-String" String="(?:br|rb)'''" insensitive="true" context="#pop!Raw Triple A-B-String" beginRegion="Triple A-region"/>
+ <RegExpr attribute="Raw B-String" String="(?:br|rb)&quot;&quot;&quot;" insensitive="true" context="#pop!Raw Triple Q-B-String" beginRegion="Triple Q-region"/>
+ <RegExpr attribute="Raw B-String" String="(?:br|rb)'" insensitive="true" context="#pop!Raw A-B-String"/>
+ <RegExpr attribute="Raw B-String" String="(?:br|rb)&quot;" insensitive="true" context="#pop!Raw Q-B-String"/>
+ </context>
+
+ <!-- https://docs.python.org/2/reference/lexical_analysis.html#string-literals -->
+ <!-- https://docs.python.org/3/reference/lexical_analysis.html#string-and-bytes-literals -->
<context name="CommentVariants" attribute="Normal Text" lineEndContext="#stay">
- <DetectSpaces/>
-
- <RegExpr attribute="Comment" String="u?'''" insensitive="true" firstNonSpace="true" context="Triple A-comment" beginRegion="Triple A-region"/>
- <RegExpr attribute="Comment" String="u?&quot;&quot;&quot;" insensitive="true" firstNonSpace="true" context="Triple Q-comment" beginRegion="Triple Q-region"/>
- <RegExpr attribute="Comment" String="u?'" insensitive="true" firstNonSpace="true" context="Single A-comment"/>
- <RegExpr attribute="Comment" String="u?&quot;" insensitive="true" firstNonSpace="true" context="Single Q-comment"/>
-
- <RegExpr attribute="Comment" String="(?:u?r|ru)'''" insensitive="true" firstNonSpace="true" context="Triple A-comment" beginRegion="Triple A-region"/>
- <RegExpr attribute="Comment" String="(?:u?r|ru)&quot;&quot;&quot;" insensitive="true" firstNonSpace="true" context="Triple Q-comment" beginRegion="Triple Q-region"/>
- <RegExpr attribute="Comment" String="(?:u?r|ru)'" insensitive="true" firstNonSpace="true" context="Single A-comment"/>
- <RegExpr attribute="Comment" String="(?:u?r|ru)&quot;" insensitive="true" firstNonSpace="true" context="Single Q-comment"/>
+ <!-- fast path -->
+ <RegExpr String="(?:u|r|ur)?['&quot;]" insensitive="true" firstNonSpace="true" context="AssumeCommentVariants" lookAhead="1"/>
+ </context>
+ <context name="AssumeCommentVariants" attribute="Normal Text" lineEndContext="#stay">
+ <RegExpr attribute="Comment" String="(?:u?r?)'''" insensitive="true" context="#pop!Triple A-comment" beginRegion="Triple A-region"/>
+ <RegExpr attribute="Comment" String="(?:u?r?)&quot;&quot;&quot;" insensitive="true" context="#pop!Triple Q-comment" beginRegion="Triple Q-region"/>
+ <RegExpr attribute="Comment" String="(?:u?r?)'" insensitive="true" context="#pop!Single A-comment"/>
+ <RegExpr attribute="Comment" String="(?:u?r?)&quot;" insensitive="true" context="#pop!Single Q-comment"/>
</context>
<context name="Dictionary" attribute="Normal Text" lineEndContext="#stay" noIndentationBasedFolding="true">
@@ -472,35 +535,53 @@
<IncludeRules context="Normal" />
</context>
+ <context name="UnfinishedStringError" attribute="Error" lineEndContext="#stay" noIndentationBasedFolding="true">
+ <!-- A single string/comment reached the end of the line without a \ line escape -->
+ <!-- We set ALL succeeding lines to the "Error" attribute so that this error is easier to spot -->
+ </context>
+
<!-- Comments -->
<context name="Hash comment" attribute="Comment" lineEndContext="#pop">
<DetectSpaces />
<IncludeRules context="##Comments" />
+ <DetectIdentifier/>
</context>
<context name="Triple A-comment" attribute="Comment" lineEndContext="#stay" noIndentationBasedFolding="true">
- <IncludeRules context="stringescape"/>
+ <DetectSpaces/>
<StringDetect attribute="Comment" String="'''" context="#pop" endRegion="Triple A-region"/>
<IncludeRules context="##Comments" />
+ <DetectIdentifier/>
+ <IncludeRules context="stringescape"/>
+ <LineContinue attribute="String Char" context="#stay"/>
</context>
<context name="Triple Q-comment" attribute="Comment" lineEndContext="#stay" noIndentationBasedFolding="true">
- <IncludeRules context="stringescape"/>
+ <DetectSpaces/>
<StringDetect attribute="Comment" String="&quot;&quot;&quot;" context="#pop" endRegion="Triple Q-region"/>
<IncludeRules context="##Comments" />
+ <DetectIdentifier/>
+ <IncludeRules context="stringescape"/>
+ <LineContinue attribute="String Char" context="#stay"/>
</context>
- <context name="Single A-comment" attribute="Comment" lineEndContext="#stay">
- <IncludeRules context="stringescape"/>
+ <context name="Single A-comment" attribute="Comment" lineEndContext="#pop!UnfinishedStringError">
+ <DetectSpaces/>
<DetectChar attribute="Comment" char="'" context="#pop"/>
<IncludeRules context="##Comments" />
+ <DetectIdentifier/>
+ <IncludeRules context="stringescape"/>
+ <LineContinue attribute="String Char" context="#stay"/>
</context>
- <context name="Single Q-comment" attribute="Comment" lineEndContext="#stay">
- <IncludeRules context="stringescape"/>
+ <context name="Single Q-comment" attribute="Comment" lineEndContext="#pop!UnfinishedStringError">
+ <DetectSpaces/>
<DetectChar attribute="Comment" char="&quot;" context="#pop"/>
<IncludeRules context="##Comments" />
+ <DetectIdentifier/>
+ <IncludeRules context="stringescape"/>
+ <LineContinue attribute="String Char" context="#stay"/>
</context>
<!-- Strings -->
@@ -520,14 +601,25 @@
<RegExpr attribute="String Char" String="\\[\\'&quot;abfnrtv]|\\[0-7]{1,3}|\\x[0-9A-Fa-f]{2}|\\u[0-9A-Fa-f]{4}|\\U[0-9A-Fa-f]{8}|\\N\{[a-zA-Z0-9\- ]+\}" context="#stay"/>
</context>
+ <!-- escape characters -->
+ <context name="bytesescape" attribute="String Char" lineEndContext="#stay">
+ <!-- As this highlighting style is for both, Python 2 and 3,
+ we do not know if a normal string is “unicode” or not. So we
+ -->
+ <RegExpr attribute="String Char" String="\\[\\'&quot;abfnrtv]|\\[0-7]{1,3}|\\x[0-9A-Fa-f]{2}" context="#stay"/>
+ </context>
+
<!-- f-literals -->
<context name="stringinterpolation" attribute="F-String" lineEndContext="#stay">
<Detect2Chars attribute="String Char" char="{" char1="{" context="#stay"/>
<DetectChar attribute="String Substitution" char="{" context="String Interpolation"/>
+ <Detect2Chars attribute="String Char" char="}" char1="}" context="#stay"/>
+ <DetectChar attribute="Error" char="}" context="#stay"/>
</context>
<context name="String Interpolation" attribute="String Substitution" lineEndContext="#stay">
<DetectChar attribute="Error" char="\" context="#pop"/>
- <RegExpr attribute="String Substitution" String="(?:![rs])?(?::(?:[^}]?[&lt;&gt;=^])?[ +-]?#?0?[0-9]*(?:\.[0-9]+)?[bcdeEfFgGnosxX%]?)?\}" context="#pop"/>
+ <!-- format specifiers: [[fill]align][sign][#][0][minimumwidth][.precision][type] -->
+ <RegExpr attribute="String Substitution" String="(?:![rsa])?(?::(?:[^}]?[&lt;&gt;=^])?[ +-]?#?0?[0-9]*(?:\.[0-9]+)?[bcdeEfFgGnosxX%]?)?\}" context="#pop"/>
<IncludeRules context="Normal"/> <!-- TODO: create expression context instead -->
</context>
@@ -542,107 +634,218 @@
Adding byte literals wouldn’t make the current 2⁴ into 2⁵ contexts, as there are no byte f-literals
-->
-
<!-- Triple-quoted A-strings -->
<context name="Triple A-string" attribute="String" lineEndContext="#stay" noIndentationBasedFolding="true">
+ <DetectSpaces attribute="String"/>
+ <DetectIdentifier attribute="String"/>
<IncludeRules context="stringescape"/>
<IncludeRules context="stringformat"/>
<StringDetect attribute="String" String="'''" context="#pop!#CheckForString" endRegion="Triple A-region"/>
+ <LineContinue attribute="String Char" context="#stay"/>
</context>
<context name="Raw Triple A-string" attribute="Raw String" lineEndContext="#stay" noIndentationBasedFolding="true">
- <HlCStringChar attribute="Raw String" context="#stay"/>
+ <DetectSpaces attribute="Raw String"/>
+ <DetectIdentifier attribute="Raw String"/>
+ <Detect2Chars attribute="Raw String" char="\" char1="'"/>
+ <Detect2Chars attribute="Raw String" char="\" char1="\"/>
<IncludeRules context="stringformat"/>
<StringDetect attribute="Raw String" String="'''" context="#pop!#CheckForString" endRegion="Triple A-region"/>
</context>
<context name="Triple A-F-String" attribute="F-String" lineEndContext="#stay" noIndentationBasedFolding="true">
+ <DetectSpaces attribute="F-String"/>
+ <DetectIdentifier attribute="F-String"/>
<IncludeRules context="stringescape"/>
<IncludeRules context="stringinterpolation"/>
<StringDetect attribute="F-String" String="'''" context="#pop!#CheckForString" endRegion="Triple A-region"/>
+ <LineContinue attribute="String Char" context="#stay"/>
</context>
<context name="Raw Triple A-F-String" attribute="Raw F-String" lineEndContext="#stay" noIndentationBasedFolding="true">
- <HlCStringChar attribute="Raw F-String" context="#stay"/>
+ <DetectSpaces attribute="Raw F-String"/>
+ <DetectIdentifier attribute="Raw F-String"/>
+ <Detect2Chars attribute="Raw F-String" char="\" char1="'"/>
+ <Detect2Chars attribute="Raw F-String" char="\" char1="\"/>
<IncludeRules context="stringinterpolation"/>
<StringDetect attribute="Raw F-String" String="'''" context="#pop!#CheckForString" endRegion="Triple A-region"/>
</context>
+ <context name="Triple A-B-String" attribute="B-String" lineEndContext="#stay" noIndentationBasedFolding="true">
+ <RegExpr attribute="B-String" String="([\x20-\x26\x28-\x5B\x5D-\x7E]++|\\(?=[^\\'&quot;abfnrtvx0-7])|\\x(?![0-9a-fA-F]{2})|'(?!''))++"/>
+ <IncludeRules context="bytesescape"/>
+ <StringDetect attribute="B-String" String="'''" context="#pop!#CheckForString" endRegion="Triple A-region"/>
+ <LineContinue attribute="String Char" context="#stay"/>
+ <RegExpr attribute="Error" String="."/>
+ </context>
+
+ <context name="Raw Triple A-B-String" attribute="Raw B-String" lineEndContext="#stay" noIndentationBasedFolding="true">
+ <RegExpr attribute="Raw B-String" String="([\x20-\x26\x28-\x5B\x5D-\x7E]++|\\.?|'(?!''))++"/>
+ <StringDetect attribute="Raw B-String" String="'''" context="#pop!#CheckForString" endRegion="Triple A-region"/>
+ <RegExpr attribute="Error" String="."/>
+ </context>
+
<!-- Triple-quoted Q-strings -->
<context name="Triple Q-string" attribute="String" lineEndContext="#stay" noIndentationBasedFolding="true">
+ <DetectSpaces attribute="String"/>
+ <DetectIdentifier attribute="String"/>
<IncludeRules context="stringescape"/>
<IncludeRules context="stringformat"/>
<StringDetect attribute="String" String="&quot;&quot;&quot;" context="#pop!#CheckForString" endRegion="Triple Q-region"/>
+ <LineContinue attribute="String Char" context="#stay"/>
</context>
<context name="Raw Triple Q-string" attribute="Raw String" lineEndContext="#stay" noIndentationBasedFolding="true">
- <HlCStringChar attribute="Raw String" context="#stay"/>
+ <DetectSpaces attribute="Raw String"/>
+ <DetectIdentifier attribute="Raw String"/>
+ <Detect2Chars attribute="Raw String" char="\" char1="&quot;"/>
+ <Detect2Chars attribute="Raw String" char="\" char1="\"/>
<IncludeRules context="stringformat"/>
<StringDetect attribute="Raw String" String="&quot;&quot;&quot;" context="#pop!#CheckForString" endRegion="Triple Q-region"/>
</context>
<context name="Triple Q-F-String" attribute="F-String" lineEndContext="#stay" noIndentationBasedFolding="true">
+ <DetectSpaces attribute="F-String"/>
+ <DetectIdentifier attribute="F-String"/>
<IncludeRules context="stringescape"/>
<IncludeRules context="stringinterpolation"/>
<StringDetect attribute="F-String" String="&quot;&quot;&quot;" context="#pop!#CheckForString" endRegion="Triple Q-region"/>
+ <LineContinue attribute="String Char" context="#stay"/>
</context>
<context name="Raw Triple Q-F-String" attribute="Raw F-String" lineEndContext="#stay" noIndentationBasedFolding="true">
- <HlCStringChar attribute="Raw F-String" context="#stay"/>
+ <DetectSpaces attribute="Raw F-String"/>
+ <DetectIdentifier attribute="Raw F-String"/>
+ <Detect2Chars attribute="Raw F-String" char="\" char1="&quot;"/>
+ <Detect2Chars attribute="Raw F-String" char="\" char1="\"/>
<IncludeRules context="stringinterpolation"/>
<StringDetect attribute="Raw F-String" String="&quot;&quot;&quot;" context="#pop!#CheckForString" endRegion="Triple Q-region"/>
</context>
+ <context name="Triple Q-B-String" attribute="B-String" lineEndContext="#stay" noIndentationBasedFolding="true">
+ <RegExpr attribute="B-String" String="([\x20\x21\x23-\x5B\x5D-\x7E]++|\\(?=[^\\'&quot;abfnrtvx0-7])|\\x(?![0-9a-fA-F]{2})|&quot;(?!&quot;&quot;))++"/>
+ <IncludeRules context="bytesescape"/>
+ <StringDetect attribute="B-String" String="&quot;&quot;&quot;" context="#pop!#CheckForString" endRegion="Triple Q-region"/>
+ <LineContinue attribute="String Char" context="#stay"/>
+ <RegExpr attribute="Error" String="."/>
+ </context>
+
+ <context name="Raw Triple Q-B-String" attribute="Raw B-String" lineEndContext="#stay" noIndentationBasedFolding="true">
+ <RegExpr attribute="Raw B-String" String="([\x20\x21\x23-\x5B\x5D-\x7E]++|\\.?|&quot;(?!&quot;&quot;))++"/>
+ <StringDetect attribute="Raw B-String" String="&quot;&quot;&quot;" context="#pop!#CheckForString" endRegion="Triple Q-region"/>
+ <RegExpr attribute="Error" String="."/>
+ </context>
+
<!-- Single-quoted A-strings -->
- <context name="Single A-string" attribute="String" lineEndContext="#stay">
+ <context name="Single A-string" attribute="String" lineEndContext="#pop!UnfinishedStringError">
+ <DetectSpaces attribute="String"/>
+ <DetectIdentifier attribute="String"/>
<IncludeRules context="stringescape"/>
<IncludeRules context="stringformat"/>
<DetectChar attribute="String" char="'" context="#pop!#CheckForString"/>
+ <LineContinue attribute="String Char" context="#stay"/>
</context>
- <context name="Raw A-string" attribute="Raw String" lineEndContext="#stay">
- <HlCStringChar attribute="Raw String" context="#stay"/>
+ <context name="Raw A-string" attribute="Raw String" lineEndContext="#pop!UnfinishedStringError">
+ <DetectSpaces attribute="Raw String"/>
+ <DetectIdentifier attribute="Raw String"/>
+ <Detect2Chars attribute="Raw String" char="\" char1="'"/>
+ <Detect2Chars attribute="Raw String" char="\" char1="\"/>
<IncludeRules context="stringformat"/>
<DetectChar attribute="Raw String" char="'" context="#pop!#CheckForString"/>
+ <LineContinue attribute="Raw String" context="#stay"/>
</context>
- <context name="Single A-F-String" attribute="F-String" lineEndContext="#stay">
+ <context name="Single A-F-String" attribute="F-String" lineEndContext="#pop!UnfinishedStringError">
+ <DetectSpaces attribute="F-String"/>
+ <DetectIdentifier attribute="F-String"/>
<IncludeRules context="stringescape"/>
<IncludeRules context="stringinterpolation"/>
<DetectChar attribute="F-String" char="'" context="#pop!#CheckForString"/>
+ <LineContinue attribute="String Char" context="#stay"/>
</context>
- <context name="Raw A-F-String" attribute="Raw F-String" lineEndContext="#stay">
- <HlCStringChar attribute="Raw F-String" context="#stay"/>
+ <context name="Raw A-F-String" attribute="Raw F-String" lineEndContext="#pop!UnfinishedStringError">
+ <DetectSpaces attribute="Raw F-String"/>
+ <DetectIdentifier attribute="Raw F-String"/>
+ <Detect2Chars attribute="Raw F-String" char="\" char1="'"/>
+ <Detect2Chars attribute="Raw F-String" char="\" char1="\"/>
<IncludeRules context="stringinterpolation"/>
<DetectChar attribute="Raw F-String" char="'" context="#pop!#CheckForString"/>
+ <LineContinue attribute="Raw F-String" context="#stay"/>
+ </context>
+
+ <context name="Single A-B-String" attribute="B-String" lineEndContext="#pop!UnfinishedStringError">
+ <RegExpr attribute="B-String" String="([\x20-\x26\x28-\x5B\x5D-\x7E]++|\\(?=[^\\'&quot;abfnrtvx0-7])|\\x(?![0-9a-fA-F]{2}))++"/>
+ <IncludeRules context="bytesescape"/>
+ <DetectChar attribute="B-String" char="'" context="#pop!#CheckForString"/>
+ <LineContinue attribute="String Char" context="#stay"/>
+ <RegExpr attribute="Error" String="."/>
+ </context>
+
+ <context name="Raw A-B-String" attribute="Raw B-String" lineEndContext="#pop!UnfinishedStringError">
+ <RegExpr attribute="Raw B-String" String="([\x20-\x26\x28-\x5B\x5D-\x7E]++|\\.)++"/>
+ <DetectChar attribute="Raw B-String" char="'" context="#pop!#CheckForString"/>
+ <LineContinue attribute="Raw B-String" context="#stay"/>
+ <RegExpr attribute="Error" String="."/>
</context>
<!-- Single-quoted Q-strings -->
- <context name="Single Q-string" attribute="String" lineEndContext="#stay">
+ <context name="Single Q-string" attribute="String" lineEndContext="#pop!UnfinishedStringError">
+ <DetectSpaces attribute="String"/>
+ <DetectIdentifier attribute="String"/>
<IncludeRules context="stringescape"/>
<IncludeRules context="stringformat"/>
<DetectChar attribute="String" char="&quot;" context="#pop!#CheckForString"/>
+ <LineContinue attribute="String Char" context="#stay"/>
</context>
- <context name="Raw Q-string" attribute="Raw String" lineEndContext="#stay">
- <HlCStringChar attribute="Raw String" context="#stay"/>
+ <context name="Raw Q-string" attribute="Raw String" lineEndContext="#pop!UnfinishedStringError">
+ <DetectSpaces attribute="Raw String"/>
+ <DetectIdentifier attribute="Raw String"/>
+ <Detect2Chars attribute="Raw String" char="\" char1="&quot;"/>
+ <Detect2Chars attribute="Raw String" char="\" char1="\"/>
<IncludeRules context="stringformat"/>
<DetectChar attribute="Raw String" char="&quot;" context="#pop!#CheckForString"/>
+ <LineContinue attribute="Raw String" context="#stay"/>
</context>
- <context name="Single Q-F-String" attribute="F-String" lineEndContext="#stay">
+ <context name="Single Q-F-String" attribute="F-String" lineEndContext="#pop!UnfinishedStringError">
+ <DetectSpaces attribute="F-String"/>
+ <DetectIdentifier attribute="F-String"/>
<IncludeRules context="stringescape"/>
<IncludeRules context="stringinterpolation"/>
<DetectChar attribute="F-String" char="&quot;" context="#pop!#CheckForString"/>
+ <LineContinue attribute="String Char" context="#stay"/>
</context>
- <context name="Raw Q-F-String" attribute="Raw F-String" lineEndContext="#stay">
- <HlCStringChar attribute="Raw F-String" context="#stay"/>
+ <context name="Raw Q-F-String" attribute="Raw F-String" lineEndContext="#pop!UnfinishedStringError">
+ <DetectSpaces attribute="Raw F-String"/>
+ <DetectIdentifier attribute="Raw F-String"/>
+ <Detect2Chars attribute="Raw F-String" char="\" char1="&quot;"/>
+ <Detect2Chars attribute="Raw F-String" char="\" char1="\"/>
<IncludeRules context="stringinterpolation"/>
<DetectChar attribute="Raw F-String" char="&quot;" context="#pop!#CheckForString"/>
+ <LineContinue attribute="Raw F-String" context="#stay"/>
</context>
+
+ <context name="Single Q-B-String" attribute="B-String" lineEndContext="#pop!UnfinishedStringError">
+ <RegExpr attribute="B-String" String="([\x20\x21\x23-\x5B\x5D-\x7E]++|\\(?=[^\\'&quot;abfnrtvx0-7])|\\x(?![0-9a-fA-F]{2}))++"/>
+ <IncludeRules context="bytesescape"/>
+ <DetectChar attribute="B-String" char="&quot;" context="#pop!#CheckForString"/>
+ <LineContinue attribute="String Char" context="#stay"/>
+ <RegExpr attribute="Error" String="."/>
+ </context>
+
+ <context name="Raw Q-B-String" attribute="Raw B-String" lineEndContext="#pop!UnfinishedStringError">
+ <RegExpr attribute="Raw B-String" String="([\x20\x21\x23-\x5B\x5D-\x7E]++|\\.)++"/>
+ <DetectChar attribute="Raw B-String" char="&quot;" context="#pop!#CheckForString"/>
+ <Detect2Chars attribute="Raw B-String" char="\" char1="\"/>
+ <LineContinue attribute="Raw B-String" context="#stay"/>
+ <RegExpr attribute="Error" String="."/>
+ </context>
+
</contexts>
<itemDatas>
@@ -668,6 +871,8 @@
<itemData name="Raw String" defStyleNum="dsVerbatimString"/>
<itemData name="F-String" defStyleNum="dsSpecialString"/>
<itemData name="Raw F-String" defStyleNum="dsVerbatimString"/>
+ <itemData name="B-String" defStyleNum="dsString" spellChecking="false"/>
+ <itemData name="Raw B-String" defStyleNum="dsVerbatimString" spellChecking="false"/>
<itemData name="String Char" defStyleNum="dsChar" spellChecking="false"/>
<itemData name="String Substitution" defStyleNum="dsSpecialChar" spellChecking="false"/>
<itemData name="Decorator" defStyleNum="dsAttribute" spellChecking="false"/>
diff --git a/src/libs/3rdparty/syntax-highlighting/data/syntax/xml.xml b/src/libs/3rdparty/syntax-highlighting/data/syntax/xml.xml
index fbefcb6dad..839e8f9162 100644
--- a/src/libs/3rdparty/syntax-highlighting/data/syntax/xml.xml
+++ b/src/libs/3rdparty/syntax-highlighting/data/syntax/xml.xml
@@ -6,7 +6,7 @@
<!ENTITY name "(?![0-9])[\w_:][\w.:_-]*">
<!ENTITY entref "&amp;(?:#[0-9]+|#[xX][0-9A-Fa-f]+|&name;);">
]>
-<language name="XML" version="12" kateversion="5.0" section="Markup" extensions="*.docbook;*.xml;*.rc;*.daml;*.rdf;*.rss;*.xspf;*.xsd;*.svg;*.ui;*.kcfg;*.qrc;*.wsdl;*.scxml;*.xbel;*.dae;*.sch;*.brd" mimetype="text/xml;text/book;text/daml;text/rdf;application/rss+xml;application/xspf+xml;image/svg+xml;application/x-designer;application/x-xbel;application/xml;application/scxml+xml" casesensitive="1" indenter="xml" author="Wilbert Berendsen (wilbert@kde.nl)" license="LGPL">
+<language name="XML" version="14" kateversion="5.0" section="Markup" extensions="*.docbook;*.xml;*.rc;*.daml;*.rdf;*.rss;*.xspf;*.xsd;*.svg;*.ui;*.kcfg;*.qrc;*.wsdl;*.scxml;*.xbel;*.dae;*.sch;*.brd" mimetype="text/xml;text/book;text/daml;text/rdf;application/rss+xml;application/xspf+xml;image/svg+xml;application/x-designer;application/x-xbel;application/xml;application/scxml+xml" casesensitive="1" indenter="xml" author="Wilbert Berendsen (wilbert@kde.nl)" license="LGPL">
<highlighting>
<contexts>
@@ -16,13 +16,13 @@
<context name="FindXML" attribute="Normal Text" lineEndContext="#stay">
<DetectSpaces />
+ <DetectIdentifier />
+ <RegExpr attribute="Element Symbols" context="ElementTagName" String="&lt;(?=(&name;))" beginRegion="element" />
<StringDetect attribute="Comment" context="Comment" String="&lt;!--" beginRegion="comment" />
<StringDetect attribute="CDATA" context="CDATAStart" String="&lt;![CDATA[" lookAhead="true" />
- <RegExpr attribute="Doctype Symbols" context="DoctypeTagName" String="&lt;!(?=DOCTYPE\s+)" beginRegion="doctype" />
+ <RegExpr attribute="Doctype Symbols" context="DoctypeTagName" String="&lt;!(?=DOCTYPE(\s|$))" beginRegion="doctype" />
<IncludeRules context="FindProcessingInstruction" />
- <RegExpr attribute="Element Symbols" context="ElementTagName" String="&lt;(?=(&name;))" beginRegion="element" />
<IncludeRules context="FindEntityRefs" />
- <DetectIdentifier />
</context>
<context name="FindEntityRefs" attribute="Other Text" lineEndContext="#stay">
@@ -70,13 +70,13 @@
<context name="PI-XML" attribute="Other Text" lineEndContext="#stay">
<IncludeRules context="PI" />
<RegExpr attribute="Attribute" context="#stay" String="(?:^|\s+)&name;" />
- <DetectChar attribute="Attribute" context="Value" char="=" />
+ <DetectChar attribute="Attribute Separator" context="Value" char="=" />
</context>
<context name="DoctypeTagName" attribute="Other Text" lineEndContext="#pop">
<StringDetect attribute="Doctype" context="#pop!DoctypeVariableName" String="DOCTYPE" />
</context>
- <context name="DoctypeVariableName" attribute="Other Text" lineEndContext="#pop!Doctype" fallthrough="true" fallthroughContext="#pop!Doctype">
+ <context name="DoctypeVariableName" attribute="Other Text" lineEndContext="#stay" fallthrough="true" fallthroughContext="#pop!Doctype">
<DetectSpaces />
<RegExpr attribute="Doctype Name" context="#pop!Doctype" String="&name;" />
</context>
@@ -116,7 +116,7 @@
<IncludeRules context="FindPEntityRefs" />
</context>
- <context name="ElementTagName" attribute="Other Text" lineEndContext="#pop!Element" fallthrough="true" fallthroughContext="#pop!Element">
+ <context name="ElementTagName" attribute="Other Text" lineEndContext="#pop!Element">
<StringDetect attribute="Element" context="#pop!Element" String="%1" dynamic="true" />
</context>
<context name="Element" attribute="Other Text" lineEndContext="#stay">
@@ -131,7 +131,7 @@
<IncludeRules context="FindXML" />
</context>
- <context name="El End TagName" attribute="Other Text" lineEndContext="#pop!El End" fallthrough="true" fallthroughContext="#pop!El End">
+ <context name="El End TagName" attribute="Other Text" lineEndContext="#pop!El End">
<StringDetect attribute="Element" context="#pop!El End" String="%1" dynamic="true" />
</context>
<context name="El End" attribute="Other Text" lineEndContext="#stay">
@@ -140,7 +140,7 @@
</context>
<context name="Attribute" attribute="Other Text" lineEndContext="#stay">
- <DetectChar attribute="Attribute" context="#pop!Value" char="=" />
+ <DetectChar attribute="Attribute Separator" context="#pop!Value" char="=" />
<RegExpr attribute="Error" context="#stay" String="\S" />
</context>
@@ -175,6 +175,7 @@
<itemData name="Element" defStyleNum="dsKeyword" spellChecking="false" />
<itemData name="Element Symbols" defStyleNum="dsNormal" spellChecking="false" />
<itemData name="Attribute" defStyleNum="dsOthers" spellChecking="false" />
+ <itemData name="Attribute Separator" defStyleNum="dsOthers" spellChecking="false" />
<itemData name="Value" defStyleNum="dsString" spellChecking="false" />
<itemData name="EntityRef" defStyleNum="dsDecVal" spellChecking="false" />
<itemData name="PEntityRef" defStyleNum="dsDecVal" spellChecking="false" />
diff --git a/src/libs/3rdparty/syntax-highlighting/data/themes/ayu-dark.theme b/src/libs/3rdparty/syntax-highlighting/data/themes/ayu-dark.theme
index ebfde02797..fea8def01f 100644
--- a/src/libs/3rdparty/syntax-highlighting/data/themes/ayu-dark.theme
+++ b/src/libs/3rdparty/syntax-highlighting/data/themes/ayu-dark.theme
@@ -1,6 +1,6 @@
{
"_comments": [
- "Last update: Feb 22, 2021 (revision 3)",
+ "Last update: Jul 28, 2021 (revision 4)",
"This file has been converted from: https://github.com/dempfi/ayu",
"Also see: https://github.com/ayu-theme"
],
@@ -11,7 +11,7 @@
],
"license": "SPDX-License-Identifier: MIT",
"name": "ayu Dark",
- "revision": 3
+ "revision": 4
},
"editor-colors": {
"BackgroundColor": "#0a0e14",
@@ -169,8 +169,8 @@
"text-color": "#39bae6"
},
"VerbatimString": {
- "selected-text-color": "#c2d94c",
- "text-color": "#c2d94c"
+ "selected-text-color": "#99ca44",
+ "text-color": "#99ca44"
},
"Warning": {
"selected-text-color": "#f07178",
diff --git a/src/libs/3rdparty/syntax-highlighting/data/themes/ayu-light.theme b/src/libs/3rdparty/syntax-highlighting/data/themes/ayu-light.theme
index c93e414457..30e119ed1b 100644
--- a/src/libs/3rdparty/syntax-highlighting/data/themes/ayu-light.theme
+++ b/src/libs/3rdparty/syntax-highlighting/data/themes/ayu-light.theme
@@ -1,6 +1,6 @@
{
"_comments": [
- "Last update: Sep 21, 2020 (revision 2)",
+ "Last update: Jul 28, 2021 (revision 3)",
"This file has been converted from: https://github.com/dempfi/ayu",
"Also see: https://github.com/ayu-theme"
],
@@ -11,7 +11,7 @@
],
"license": "SPDX-License-Identifier: MIT",
"name": "ayu Light",
- "revision": 2
+ "revision": 3
},
"editor-colors": {
"BackgroundColor": "#fafafa",
@@ -169,8 +169,8 @@
"text-color": "#55b4d4"
},
"VerbatimString": {
- "selected-text-color": "#86b300",
- "text-color": "#86b300"
+ "selected-text-color": "#729800",
+ "text-color": "#729800"
},
"Warning": {
"selected-text-color": "#f07171",
diff --git a/src/libs/3rdparty/syntax-highlighting/data/themes/ayu-mirage.theme b/src/libs/3rdparty/syntax-highlighting/data/themes/ayu-mirage.theme
index e389ecf298..005d6a0ad2 100644
--- a/src/libs/3rdparty/syntax-highlighting/data/themes/ayu-mirage.theme
+++ b/src/libs/3rdparty/syntax-highlighting/data/themes/ayu-mirage.theme
@@ -1,6 +1,6 @@
{
"_comments": [
- "Last update: Feb 22, 2021 (revision 3)",
+ "Last update: Jul 28, 2021 (revision 4)",
"This file has been converted from: https://github.com/dempfi/ayu",
"Also see: https://github.com/ayu-theme"
],
@@ -11,7 +11,7 @@
],
"license": "SPDX-License-Identifier: MIT",
"name": "ayu Mirage",
- "revision": 3
+ "revision": 4
},
"editor-colors": {
"BackgroundColor": "#1f2430",
@@ -169,8 +169,8 @@
"text-color": "#5ccfe6"
},
"VerbatimString": {
- "selected-text-color": "#bae67e",
- "text-color": "#bae67e"
+ "selected-text-color": "#82e26a",
+ "text-color": "#82e26a"
},
"Warning": {
"selected-text-color": "#f28779",
diff --git a/src/libs/3rdparty/syntax-highlighting/data/themes/breeze-dark.theme b/src/libs/3rdparty/syntax-highlighting/data/themes/breeze-dark.theme
index 712da4acc4..1ad7fffee3 100644
--- a/src/libs/3rdparty/syntax-highlighting/data/themes/breeze-dark.theme
+++ b/src/libs/3rdparty/syntax-highlighting/data/themes/breeze-dark.theme
@@ -5,7 +5,7 @@
"SPDX-FileCopyrightText: 2016 Dominik Haumann <dhaumann@kde.org>"
],
"license": "SPDX-License-Identifier: MIT",
- "revision" : 6,
+ "revision" : 7,
"name" : "Breeze Dark"
},
"text-styles": {
@@ -149,7 +149,7 @@
"editor-colors": {
"BackgroundColor" : "#232629",
"CodeFolding" : "#224e65",
- "BracketMatching" : "#323030",
+ "BracketMatching" : "#8e44ad",
"CurrentLine" : "#2A2E32",
"IconBorder" : "#31363b",
"IndentationLine" : "#3a3f44",
diff --git a/src/libs/3rdparty/syntax-highlighting/data/themes/breeze-light.theme b/src/libs/3rdparty/syntax-highlighting/data/themes/breeze-light.theme
index 7d0116bea9..6dee8dd777 100644
--- a/src/libs/3rdparty/syntax-highlighting/data/themes/breeze-light.theme
+++ b/src/libs/3rdparty/syntax-highlighting/data/themes/breeze-light.theme
@@ -5,7 +5,7 @@
"SPDX-FileCopyrightText: 2016 Dominik Haumann <dhaumann@kde.org>"
],
"license": "SPDX-License-Identifier: MIT",
- "revision" : 8,
+ "revision" : 9,
"name" : "Breeze Light"
},
"text-styles": {
@@ -70,7 +70,7 @@
"selected-text-color" : "#9c0e0e"
},
"VerbatimString" : {
- "text-color" : "#bf0303",
+ "text-color" : "#e31616",
"selected-text-color" : "#9c0e0e"
},
"SpecialString" : {
diff --git a/src/libs/3rdparty/syntax-highlighting/data/themes/dracula.theme b/src/libs/3rdparty/syntax-highlighting/data/themes/dracula.theme
index 93b1833334..b388396050 100644
--- a/src/libs/3rdparty/syntax-highlighting/data/themes/dracula.theme
+++ b/src/libs/3rdparty/syntax-highlighting/data/themes/dracula.theme
@@ -570,7 +570,7 @@
],
"license": "SPDX-License-Identifier: MIT",
"name": "Dracula",
- "revision": 7
+ "revision": 8
},
"text-styles": {
"Alert": {
@@ -694,8 +694,8 @@
"text-color": "#8be9fd"
},
"VerbatimString": {
- "selected-text-color": "#f1fa8c",
- "text-color": "#f1fa8c"
+ "selected-text-color": "#d7e60a",
+ "text-color": "#d7e60a"
},
"Warning": {
"selected-text-color": "#ff5555",
diff --git a/src/libs/3rdparty/syntax-highlighting/data/themes/falcon.theme b/src/libs/3rdparty/syntax-highlighting/data/themes/falcon.theme
new file mode 100644
index 0000000000..1ebf8c6946
--- /dev/null
+++ b/src/libs/3rdparty/syntax-highlighting/data/themes/falcon.theme
@@ -0,0 +1,184 @@
+{
+ "_comments": [
+ "A theme focused on ergonomics, using the 3 digit Tango color palette"
+ ],
+ "metadata": {
+ "name": "Falcon",
+ "revision": 4,
+ "license": "SPDX-License-Identifier: MIT",
+ "copyright": [ "SPDX-FileCopyrightText: 2021 Alberto Salvia Novella <https://es20490446e.wordpress.com>" ]
+ },
+ "custom-styles": {
+ "Bash": {
+ "Normal Text": {
+ "text-color": "#bbbbbb"
+ }
+ }
+ },
+ "editor-colors": {
+ "BackgroundColor": "#223333",
+ "BracketMatching": "#555555",
+ "CodeFolding": "#224488",
+ "CurrentLine": "#555555",
+ "CurrentLineNumber": "#bbbbbb",
+ "IconBorder": "#223333",
+ "IndentationLine": "#888888",
+ "LineNumbers": "#888888",
+ "MarkBookmark": "#7799cc",
+ "MarkBreakpointActive": "#ffaa33",
+ "MarkBreakpointDisabled": "#aa77aa",
+ "MarkBreakpointReached": "#449900",
+ "MarkError": "#ef2929",
+ "MarkExecution": "#888888",
+ "MarkWarning": "#aa77aa",
+ "ModifiedLines": "#aa0000",
+ "ReplaceHighlight": "#224488",
+ "SavedLines": "#449900",
+ "SearchHighlight": "#224488",
+ "Separator": "#555753",
+ "SpellChecking": "#ef2929",
+ "TabMarker": "#555555",
+ "TemplateBackground": "#223333",
+ "TemplateFocusedPlaceholder": "#23321a",
+ "TemplatePlaceholder": "#23321a",
+ "TemplateReadOnlyPlaceholder": "#451e1a",
+ "TextSelection": "#3366aa",
+ "WordWrapMarker": "#555753"
+ },
+ "text-styles": {
+ "Alert": {
+ "background-color": "#320000",
+ "bold": true,
+ "selected-text-color": "#ffaa33",
+ "text-color": "#ee2222"
+ },
+ "Annotation": {
+ "selected-text-color": "#ddddcc",
+ "text-color": "#aa77aa"
+ },
+ "Attribute": {
+ "selected-text-color": "#ddddcc",
+ "text-color": "#aa77aa"
+ },
+ "BaseN": {
+ "selected-text-color": "#ffee44",
+ "text-color": "#eedd00"
+ },
+ "BuiltIn": {
+ "selected-text-color": "#ddddcc",
+ "text-color": "#7799cc"
+ },
+ "Char": {
+ "selected-text-color": "#ffaa33",
+ "text-color": "#ffaa33"
+ },
+ "Comment": {
+ "selected-text-color": "#eeeeec",
+ "text-color": "#888888"
+ },
+ "CommentVar": {
+ "selected-text-color": "#ddddcc",
+ "text-color": "#aa77aa"
+ },
+ "Constant": {
+ "bold": true,
+ "selected-text-color": "#ffee44",
+ "text-color": "#eedd00"
+ },
+ "ControlFlow": {
+ "bold": true,
+ "selected-text-color": "#ffee44",
+ "text-color": "#eedd00"
+ },
+ "DataType": {
+ "selected-text-color": "#ddddcc",
+ "text-color": "#7799cc"
+ },
+ "DecVal": {
+ "selected-text-color": "#ffee44",
+ "text-color": "#eedd00"
+ },
+ "Documentation": {
+ "selected-text-color": "#eeeeee",
+ "text-color": "#d3d7cf"
+ },
+ "Error": {
+ "selected-text-color": "#ffaa33",
+ "text-color": "#ee2222",
+ "underline": true
+ },
+ "Extension": {
+ "bold": true,
+ "selected-text-color": "#ddddcc",
+ "text-color": "#7799cc"
+ },
+ "Float": {
+ "selected-text-color": "#ffaa33",
+ "text-color": "#ffaa33"
+ },
+ "Function": {
+ "bold": true,
+ "selected-text-color": "#ddddcc",
+ "text-color": "#7799cc"
+ },
+ "Import": {
+ "selected-text-color": "#88ee33",
+ "text-color": "#88ee33"
+ },
+ "Information": {
+ "selected-text-color": "#eeeeee",
+ "text-color": "#ddddcc"
+ },
+ "Keyword": {
+ "bold": true,
+ "selected-text-color": "#ddddcc",
+ "text-color": "#aa77aa"
+ },
+ "Normal": {
+ "selected-text-color": "#eeeeee",
+ "text-color": "#ddddcc"
+ },
+ "Operator": {
+ "selected-text-color": "#ffee44",
+ "text-color": "#eedd00"
+ },
+ "Others": {
+ "selected-text-color": "#ffee44",
+ "text-color": "#eedd00"
+ },
+ "Preprocessor": {
+ "selected-text-color": "#ddddcc",
+ "text-color": "#aa77aa"
+ },
+ "RegionMarker": {
+ "background-color": "#0d1932",
+ "selected-text-color": "#ddddcc",
+ "text-color": "#7799cc"
+ },
+ "SpecialChar": {
+ "selected-text-color": "#ffaa33",
+ "text-color": "#ffaa33"
+ },
+ "SpecialString": {
+ "selected-text-color": "#eeeeee",
+ "text-color": "#ddddcc"
+ },
+ "String": {
+ "selected-text-color": "#eeeeee",
+ "text-color": "#ddddcc"
+ },
+ "Variable": {
+ "bold": true,
+ "selected-text-color": "#ffaa33",
+ "text-color": "#ffaa33"
+ },
+ "VerbatimString": {
+ "selected-text-color": "#ffaa33",
+ "text-color": "#ffaa33"
+ },
+ "Warning": {
+ "selected-text-color": "#ffee44",
+ "text-color": "#eedd00"
+ }
+ }
+}
diff --git a/src/libs/3rdparty/syntax-highlighting/data/themes/github-dark.theme b/src/libs/3rdparty/syntax-highlighting/data/themes/github-dark.theme
index 313e99f052..a699638532 100644
--- a/src/libs/3rdparty/syntax-highlighting/data/themes/github-dark.theme
+++ b/src/libs/3rdparty/syntax-highlighting/data/themes/github-dark.theme
@@ -82,7 +82,7 @@
],
"license": "SPDX-License-Identifier: MIT",
"name": "GitHub Dark",
- "revision": 2
+ "revision": 3
},
"text-styles": {
"Alert": {
@@ -205,8 +205,8 @@
"text-color": "#ffab70"
},
"VerbatimString": {
- "selected-text-color": "#9ecbff",
- "text-color": "#9ecbff"
+ "selected-text-color": "#41a0ff",
+ "text-color": "#41a0ff"
},
"Warning": {
"selected-text-color": "#ff5555",
diff --git a/src/libs/3rdparty/syntax-highlighting/data/themes/github-light.theme b/src/libs/3rdparty/syntax-highlighting/data/themes/github-light.theme
index 5f465c653c..ed56418fde 100644
--- a/src/libs/3rdparty/syntax-highlighting/data/themes/github-light.theme
+++ b/src/libs/3rdparty/syntax-highlighting/data/themes/github-light.theme
@@ -82,7 +82,7 @@
],
"license": "SPDX-License-Identifier: MIT",
"name": "GitHub Light",
- "revision": 2
+ "revision": 3
},
"text-styles": {
"Alert": {
@@ -205,8 +205,8 @@
"text-color": "#e36209"
},
"VerbatimString": {
- "selected-text-color": "#032f62",
- "text-color": "#032f62"
+ "selected-text-color": "#034c95",
+ "text-color": "#034c95"
},
"Warning": {
"selected-text-color": "#ff5555",
diff --git a/src/libs/3rdparty/syntax-highlighting/data/themes/gruvbox-dark.theme b/src/libs/3rdparty/syntax-highlighting/data/themes/gruvbox-dark.theme
index 66c6c9afb7..0e006ab46e 100644
--- a/src/libs/3rdparty/syntax-highlighting/data/themes/gruvbox-dark.theme
+++ b/src/libs/3rdparty/syntax-highlighting/data/themes/gruvbox-dark.theme
@@ -1,6 +1,6 @@
{
"_comments": [
- "Last update: Sep 17, 2020 (revision 2)",
+ "Last update: Jul 28, 2021 (revision 3)",
"This file has been converted from: https://github.com/morhetz/gruvbox"
],
"metadata" : {
@@ -10,7 +10,7 @@
],
"license": "SPDX-License-Identifier: MIT",
"name" : "gruvbox Dark",
- "revision" : 2
+ "revision" : 3
},
"text-styles": {
"Normal" : {
@@ -73,7 +73,7 @@
"selected-text-color" : "#b8bb26"
},
"VerbatimString" : {
- "text-color" : "#98971a",
+ "text-color" : "#848216",
"selected-text-color" : "#b8bb26"
},
"SpecialString" : {
diff --git a/src/libs/3rdparty/syntax-highlighting/data/themes/gruvbox-light.theme b/src/libs/3rdparty/syntax-highlighting/data/themes/gruvbox-light.theme
index 6038c70e94..937a43d084 100644
--- a/src/libs/3rdparty/syntax-highlighting/data/themes/gruvbox-light.theme
+++ b/src/libs/3rdparty/syntax-highlighting/data/themes/gruvbox-light.theme
@@ -1,6 +1,6 @@
{
"_comments": [
- "Last update: Sep 17, 2020 (revision 2)",
+ "Last update: Jul 28, 2021 (revision 3)",
"This file has been converted from: https://github.com/morhetz/gruvbox"
],
"metadata" : {
@@ -10,7 +10,7 @@
],
"license": "SPDX-License-Identifier: MIT",
"name" : "gruvbox Light",
- "revision" : 2
+ "revision" : 3
},
"text-styles": {
"Normal" : {
@@ -73,7 +73,7 @@
"selected-text-color" : "#79740e"
},
"VerbatimString" : {
- "text-color" : "#98971a",
+ "text-color" : "#848216",
"selected-text-color" : "#79740e"
},
"SpecialString" : {
diff --git a/src/libs/3rdparty/syntax-highlighting/data/themes/monokai.theme b/src/libs/3rdparty/syntax-highlighting/data/themes/monokai.theme
index 3df8e66c00..e0026ca3b3 100644
--- a/src/libs/3rdparty/syntax-highlighting/data/themes/monokai.theme
+++ b/src/libs/3rdparty/syntax-highlighting/data/themes/monokai.theme
@@ -259,7 +259,7 @@
],
"license": "SPDX-License-Identifier: MIT",
"name": "Monokai",
- "revision": 5
+ "revision": 6
},
"text-styles": {
"Alert": {
@@ -383,8 +383,8 @@
"text-color": "#f8f8f2"
},
"VerbatimString": {
- "selected-text-color": "#e6db74",
- "text-color": "#e6db74"
+ "selected-text-color": "#d8c72c",
+ "text-color": "#d8c72c"
},
"Warning": {
"selected-text-color": "#ff5555",
diff --git a/src/libs/3rdparty/syntax-highlighting/data/themes/nord.theme b/src/libs/3rdparty/syntax-highlighting/data/themes/nord.theme
index 6ad4d82e43..dbe44d9b09 100644
--- a/src/libs/3rdparty/syntax-highlighting/data/themes/nord.theme
+++ b/src/libs/3rdparty/syntax-highlighting/data/themes/nord.theme
@@ -1,6 +1,6 @@
{
"_comments": [
- "Last update: Sep 21, 2020 (revision 2)",
+ "Last update: Jul 28, 2020 (revision 3)",
"This theme has been adapted from: https://www.nordtheme.com"
],
"metadata": {
@@ -11,7 +11,7 @@
],
"license": "SPDX-License-Identifier: MIT",
"name": "Nord",
- "revision": 2
+ "revision": 3
},
"editor-colors": {
"BackgroundColor": "#2e3440",
@@ -170,8 +170,8 @@
"text-color": "#5e81ac"
},
"VerbatimString": {
- "selected-text-color": "#a3be8c",
- "text-color": "#a3be8c"
+ "selected-text-color": "#8dae70",
+ "text-color": "#8dae70"
},
"Warning": {
"selected-text-color": "#bf616a",
diff --git a/src/libs/3rdparty/syntax-highlighting/data/themes/printing.theme b/src/libs/3rdparty/syntax-highlighting/data/themes/printing.theme
index 26d779582d..49bbe6419f 100644
--- a/src/libs/3rdparty/syntax-highlighting/data/themes/printing.theme
+++ b/src/libs/3rdparty/syntax-highlighting/data/themes/printing.theme
@@ -5,7 +5,7 @@
"SPDX-FileCopyrightText: 2016 Dominik Haumann <dhaumann@kde.org>"
],
"license": "SPDX-License-Identifier: MIT",
- "revision" : 4,
+ "revision" : 5,
"name" : "Printing"
},
"text-styles": {
@@ -69,7 +69,7 @@
"selected-text-color" : "#9c0e0e"
},
"VerbatimString" : {
- "text-color" : "#bf0303",
+ "text-color" : "#ea0404",
"selected-text-color" : "#9c0e0e"
},
"SpecialString" : {
diff --git a/src/libs/3rdparty/syntax-highlighting/data/themes/solarized-dark.theme b/src/libs/3rdparty/syntax-highlighting/data/themes/solarized-dark.theme
index b8d13b31d3..1fe48bacd0 100644
--- a/src/libs/3rdparty/syntax-highlighting/data/themes/solarized-dark.theme
+++ b/src/libs/3rdparty/syntax-highlighting/data/themes/solarized-dark.theme
@@ -9,7 +9,7 @@
"SPDX-FileCopyrightText: 2018 Andrew Crouthamel <andrew.crouthamel@kdemail.net>"
],
"license": "SPDX-License-Identifier: MIT",
- "revision" : 5,
+ "revision" : 6,
"name" : "Solarized Dark"
},
"text-styles": {
@@ -70,8 +70,8 @@
"selected-text-color" : "#2aa198"
},
"VerbatimString" : {
- "text-color" : "#2aa198",
- "selected-text-color" : "#2aa198"
+ "text-color" : "#23877e",
+ "selected-text-color" : "#23877e"
},
"SpecialString" : {
"text-color" : "#dc322f",
diff --git a/src/libs/3rdparty/syntax-highlighting/data/themes/solarized-light.theme b/src/libs/3rdparty/syntax-highlighting/data/themes/solarized-light.theme
index a532b128f8..51c76faaec 100644
--- a/src/libs/3rdparty/syntax-highlighting/data/themes/solarized-light.theme
+++ b/src/libs/3rdparty/syntax-highlighting/data/themes/solarized-light.theme
@@ -9,7 +9,7 @@
"SPDX-FileCopyrightText: 2018 Andrew Crouthamel <andrew.crouthamel@kdemail.net>"
],
"license": "SPDX-License-Identifier: MIT",
- "revision" : 4,
+ "revision" : 5,
"name" : "Solarized Light"
},
"text-styles": {
@@ -73,8 +73,8 @@
"selected-text-color" : "#2aa198"
},
"VerbatimString" : {
- "text-color" : "#2aa198",
- "selected-text-color" : "#2aa198"
+ "text-color" : "#23837a",
+ "selected-text-color" : "#23837a"
},
"SpecialString" : {
"text-color" : "#dc322f",
diff --git a/src/libs/3rdparty/syntax-highlighting/data/themes/theme-data.qrc b/src/libs/3rdparty/syntax-highlighting/data/themes/theme-data.qrc
index fe0a1627be..cf9d658c82 100644
--- a/src/libs/3rdparty/syntax-highlighting/data/themes/theme-data.qrc
+++ b/src/libs/3rdparty/syntax-highlighting/data/themes/theme-data.qrc
@@ -9,6 +9,7 @@
<file>ayu-light.theme</file>
<file>ayu-mirage.theme</file>
<file>dracula.theme</file>
+ <file>falcon.theme</file>
<file>github-dark.theme</file>
<file>github-light.theme</file>
<file>gruvbox-dark.theme</file>
diff --git a/src/libs/3rdparty/syntax-highlighting/data/themes/vim-dark.theme b/src/libs/3rdparty/syntax-highlighting/data/themes/vim-dark.theme
index 1a2c7785ac..d039822cae 100644
--- a/src/libs/3rdparty/syntax-highlighting/data/themes/vim-dark.theme
+++ b/src/libs/3rdparty/syntax-highlighting/data/themes/vim-dark.theme
@@ -5,7 +5,7 @@
"SPDX-FileCopyrightText: 2020 Nibaldo González <nibgonz@gmail.com>"
],
"license": "SPDX-License-Identifier: MIT",
- "revision" : 3,
+ "revision" : 4,
"name" : "Vim Dark"
},
"text-styles": {
@@ -70,8 +70,8 @@
"selected-text-color" : "#ff54ff"
},
"VerbatimString" : {
- "text-color" : "#ff54ff",
- "selected-text-color" : "#ff54ff"
+ "text-color" : "#f000f0",
+ "selected-text-color" : "#f000f0"
},
"SpecialString" : {
"text-color" : "#ff5500",
diff --git a/src/libs/3rdparty/syntax-highlighting/metainfo.yaml b/src/libs/3rdparty/syntax-highlighting/metainfo.yaml
index 7a3220a31e..a82f7a986d 100644
--- a/src/libs/3rdparty/syntax-highlighting/metainfo.yaml
+++ b/src/libs/3rdparty/syntax-highlighting/metainfo.yaml
@@ -6,7 +6,7 @@ platforms:
- name: Linux
- name: FreeBSD
- name: Windows
- - name: MacOSX
+ - name: macOS
- name: Android
portingAid: false
deprecated: false
diff --git a/src/libs/3rdparty/syntax-highlighting/src/cli/kate-syntax-highlighter.cpp b/src/libs/3rdparty/syntax-highlighting/src/cli/kate-syntax-highlighter.cpp
index a009c4f259..749123aa54 100644
--- a/src/libs/3rdparty/syntax-highlighting/src/cli/kate-syntax-highlighter.cpp
+++ b/src/libs/3rdparty/syntax-highlighting/src/cli/kate-syntax-highlighter.cpp
@@ -30,10 +30,11 @@ static void applyHighlighter(Highlighter &highlighter,
const QCommandLineOption &outputName,
const Ts &...highlightParams)
{
- if (parser.isSet(outputName))
+ if (parser.isSet(outputName)) {
highlighter.setOutputFile(parser.value(outputName));
- else
+ } else {
highlighter.setOutputFile(stdout);
+ }
if (fromFileName) {
highlighter.highlightFile(inFileName, highlightParams...);
@@ -126,8 +127,9 @@ int main(int argc, char **argv)
}
if (parser.isSet(listThemes)) {
- for (const auto &theme : repo.themes())
+ for (const auto &theme : repo.themes()) {
std::cout << qPrintable(theme.name()) << std::endl;
+ }
return 0;
}
@@ -158,9 +160,10 @@ int main(int argc, char **argv)
if (!def.isValid()) {
/* see if it's a extension instead */
def = repo.definitionForFileName(QLatin1String("f.") + syntax);
- if (!def.isValid())
+ if (!def.isValid()) {
/* see if it's a filename instead */
def = repo.definitionForFileName(syntax);
+ }
}
}
} else if (fromFileName) {
@@ -177,8 +180,9 @@ int main(int argc, char **argv)
QString outputFormat = parser.value(outputFormatOption);
if (0 == outputFormat.compare(QLatin1String("html"), Qt::CaseInsensitive)) {
QString title;
- if (parser.isSet(titleOption))
+ if (parser.isSet(titleOption)) {
title = parser.value(titleOption);
+ }
HtmlHighlighter highlighter;
highlighter.setDefinition(def);
diff --git a/src/libs/3rdparty/syntax-highlighting/src/indexer/CMakeLists.txt b/src/libs/3rdparty/syntax-highlighting/src/indexer/CMakeLists.txt
index 508cd276cc..4a84696ad9 100644
--- a/src/libs/3rdparty/syntax-highlighting/src/indexer/CMakeLists.txt
+++ b/src/libs/3rdparty/syntax-highlighting/src/indexer/CMakeLists.txt
@@ -28,7 +28,8 @@ elseif(CMAKE_CROSSCOMPILING)
else()
# host build
add_executable(katehighlightingindexer katehighlightingindexer.cpp ../lib/worddelimiters.cpp)
- if(Qt5XmlPatterns_FOUND)
+ ecm_mark_nongui_executable(katehighlightingindexer)
+ if(Qt5XmlPatterns_FOUND AND NOT ECM_ENABLE_SANITIZERS)
target_link_libraries(katehighlightingindexer Qt5::XmlPatterns)
else()
target_link_libraries(katehighlightingindexer Qt5::Core)
diff --git a/src/libs/3rdparty/syntax-highlighting/src/indexer/katehighlightingindexer.cpp b/src/libs/3rdparty/syntax-highlighting/src/indexer/katehighlightingindexer.cpp
index 86b3a38b12..4de51ba7c8 100644
--- a/src/libs/3rdparty/syntax-highlighting/src/indexer/katehighlightingindexer.cpp
+++ b/src/libs/3rdparty/syntax-highlighting/src/indexer/katehighlightingindexer.cpp
@@ -31,7 +31,8 @@ using KSyntaxHighlighting::Xml::attrToBool;
class HlFilesChecker
{
public:
- void setDefinition(const QStringRef &verStr, const QString &filename, const QString &name)
+ template<typename T>
+ void setDefinition(const T &verStr, const QString &filename, const QString &name)
{
m_currentDefinition = &*m_definitions.insert(name, Definition{});
m_currentDefinition->languageName = name;
@@ -93,6 +94,12 @@ public:
continue;
}
+ auto markAsUsedContext = [](ContextName &ContextName) {
+ if (!ContextName.stay && ContextName.context) {
+ ContextName.context->isOnlyIncluded = false;
+ }
+ };
+
QMutableMapIterator<QString, Context> contextIt(contexts);
while (contextIt.hasNext()) {
contextIt.next();
@@ -100,12 +107,21 @@ public:
resolveContextName(definition, context, context.lineEndContext, context.line);
resolveContextName(definition, context, context.lineEmptyContext, context.line);
resolveContextName(definition, context, context.fallthroughContext, context.line);
+ markAsUsedContext(context.lineEndContext);
+ markAsUsedContext(context.lineEmptyContext);
+ markAsUsedContext(context.fallthroughContext);
for (auto &rule : context.rules) {
+ rule.parentContext = &context;
resolveContextName(definition, context, rule.context, rule.line);
+ if (rule.type != Context::Rule::Type::IncludeRules) {
+ markAsUsedContext(rule.context);
+ }
}
}
- definition.firstContext = &*definition.contexts.find(definition.firstContextName);
+ auto *firstContext = &*definition.contexts.find(definition.firstContextName);
+ firstContext->isOnlyIncluded = false;
+ definition.firstContext = firstContext;
}
resolveIncludeRules();
@@ -118,6 +134,7 @@ public:
const auto usedContexts = extractUsedContexts();
QMap<const Definition *, const Definition *> maxVersionByDefinitions;
+ QMap<const Context::Rule *, IncludedRuleUnreachableBy> unreachableIncludedRules;
QMapIterator<QString, Definition> def(m_definitions);
while (def.hasNext()) {
@@ -135,14 +152,7 @@ public:
QSet<const Keywords *> referencedKeywords;
QSet<ItemDatas::Style> usedAttributeNames;
success = checkKeywordsList(definition, referencedKeywords) && success;
- success = checkContexts(definition, referencedKeywords, usedAttributeNames, usedContexts) && success;
-
- // search for non-existing or unreferenced keyword lists.
- for (const auto &keywords : definition.keywordsList) {
- if (!referencedKeywords.contains(&keywords)) {
- qWarning() << filename << "line" << keywords.line << "unused keyword:" << keywords.name;
- }
- }
+ success = checkContexts(definition, referencedKeywords, usedAttributeNames, usedContexts, unreachableIncludedRules) && success;
// search for non-existing itemDatas.
const auto invalidNames = usedAttributeNames - definition.itemDatas.styleNames;
@@ -159,6 +169,56 @@ public:
}
}
+ QMutableMapIterator<const Context::Rule *, IncludedRuleUnreachableBy> unreachableIncludedRuleIt(unreachableIncludedRules);
+ while (unreachableIncludedRuleIt.hasNext()) {
+ unreachableIncludedRuleIt.next();
+ IncludedRuleUnreachableBy &unreachableRulesBy = unreachableIncludedRuleIt.value();
+ if (unreachableRulesBy.alwaysUnreachable) {
+ auto *rule = unreachableIncludedRuleIt.key();
+
+ if (!rule->parentContext->isOnlyIncluded) {
+ continue;
+ }
+
+ // remove duplicates rules
+ QSet<const Context::Rule *> rules;
+ auto &unreachableBy = unreachableRulesBy.unreachableBy;
+ unreachableBy.erase(std::remove_if(unreachableBy.begin(),
+ unreachableBy.end(),
+ [&](const RuleAndInclude &ruleAndInclude) {
+ if (rules.contains(ruleAndInclude.rule)) {
+ return true;
+ }
+ rules.insert(ruleAndInclude.rule);
+ return false;
+ }),
+ unreachableBy.end());
+
+ QString message;
+ message.reserve(128);
+ for (auto &ruleAndInclude : std::as_const(unreachableBy)) {
+ message += QStringLiteral("line ");
+ message += QString::number(ruleAndInclude.rule->line);
+ message += QStringLiteral(" [");
+ message += ruleAndInclude.rule->parentContext->name;
+ if (rule->filename != ruleAndInclude.rule->filename) {
+ message += QStringLiteral(" (");
+ message += ruleAndInclude.rule->filename;
+ message += QLatin1Char(')');
+ }
+ if (ruleAndInclude.includeRules) {
+ message += QStringLiteral(" via line ");
+ message += QString::number(ruleAndInclude.includeRules->line);
+ }
+ message += QStringLiteral("], ");
+ }
+ message.chop(2);
+
+ qWarning() << rule->filename << "line" << rule->line << "no IncludeRule can reach this rule, hidden by" << message;
+ success = false;
+ }
+ }
+
return success;
}
@@ -176,7 +236,7 @@ private:
int popCount = 0;
bool stay = false;
- const Context *context = nullptr;
+ Context *context = nullptr;
};
struct Parser {
@@ -185,12 +245,13 @@ private:
QXmlStreamAttribute &attr;
bool success;
- //! Read a string type attribute, \c sucess = \c false when \p str is not empty
+ //! Read a string type attribute, \c success = \c false when \p str is not empty
//! \return \c true when attr.name() == attrName, otherwise false
bool extractString(QString &str, const QString &attrName)
{
- if (attr.name() != attrName)
+ if (attr.name() != attrName) {
return false;
+ }
str = attr.value().toString();
if (str.isEmpty()) {
@@ -201,24 +262,26 @@ private:
return true;
}
- //! Read a bool type attribute, \c sucess = \c false when \p xmlBool is not \c XmlBool::Unspecified.
+ //! Read a bool type attribute, \c success = \c false when \p xmlBool is not \c XmlBool::Unspecified.
//! \return \c true when attr.name() == attrName, otherwise false
bool extractXmlBool(XmlBool &xmlBool, const QString &attrName)
{
- if (attr.name() != attrName)
+ if (attr.name() != attrName) {
return false;
+ }
xmlBool = attr.value().isNull() ? XmlBool::Unspecified : attrToBool(attr.value()) ? XmlBool::True : XmlBool::False;
return true;
}
- //! Read a positive integer type attribute, \c sucess = \c false when \p positive is already greater than or equal to 0
+ //! Read a positive integer type attribute, \c success = \c false when \p positive is already greater than or equal to 0
//! \return \c true when attr.name() == attrName, otherwise false
bool extractPositive(int &positive, const QString &attrName)
{
- if (attr.name() != attrName)
+ if (attr.name() != attrName) {
return false;
+ }
bool ok = true;
positive = attr.value().toInt(&ok);
@@ -231,12 +294,13 @@ private:
return true;
}
- //! Read a color, \c sucess = \c false when \p color is already greater than or equal to 0
+ //! Read a color, \c success = \c false when \p color is already greater than or equal to 0
//! \return \c true when attr.name() == attrName, otherwise false
bool checkColor(const QString &attrName)
{
- if (attr.name() != attrName)
+ if (attr.name() != attrName) {
return false;
+ }
const auto value = attr.value().toString();
if (value.isEmpty() /*|| QColor(value).isValid()*/) {
@@ -247,16 +311,17 @@ private:
return true;
}
- //! Read a QChar, \c sucess = \c false when \p c is not \c '\0' or does not have one char
+ //! Read a QChar, \c success = \c false when \p c is not \c '\0' or does not have one char
//! \return \c true when attr.name() == attrName, otherwise false
bool extractChar(QChar &c, const QString &attrName)
{
- if (attr.name() != attrName)
+ if (attr.name() != attrName) {
return false;
+ }
- if (attr.value().size() == 1)
+ if (attr.value().size() == 1) {
c = attr.value()[0];
- else {
+ } else {
c = QLatin1Char('_');
qWarning() << filename << "line" << xml.lineNumber() << attrName << "must contain exactly one char:" << attr.value();
success = false;
@@ -268,8 +333,9 @@ private:
//! \return parsing status when \p isExtracted is \c true, otherwise \c false
bool checkIfExtracted(bool isExtracted)
{
- if (isExtracted)
+ if (isExtracted) {
return success;
+ }
qWarning() << filename << "line" << xml.lineNumber() << "unknown attribute:" << attr.name();
return false;
@@ -284,7 +350,7 @@ private:
friend uint qHash(const Item &item, uint seed = 0)
{
- return qHash(item.content, seed);
+ return uint(qHash(item.content, seed));
}
friend bool operator==(const Item &item0, const Item &item1)
@@ -400,18 +466,19 @@ private:
QString additionalDeliminator;
QString weakDeliminator;
- // rules included by IncludeRules
+ // rules included by IncludeRules (without IncludeRule)
QVector<const Rule *> includedRules;
// IncludeRules included by IncludeRules
QSet<const Rule *> includedIncludeRules;
+ Context const *parentContext = nullptr;
+
QString filename;
bool parseElement(const QString &filename, QXmlStreamReader &xml)
{
this->filename = filename;
-
line = xml.lineNumber();
using Pair = QPair<QString, Type>;
@@ -579,6 +646,8 @@ private:
};
int line;
+ // becomes false when a context refers to it
+ bool isOnlyIncluded = true;
QString name;
QString attribute;
ContextName lineEndContext;
@@ -650,7 +719,7 @@ private:
friend uint qHash(const Style &style, uint seed = 0)
{
- return qHash(style.name, seed);
+ return uint(qHash(style.name, seed));
}
friend bool operator==(const Style &style0, const Style &style1)
@@ -723,8 +792,9 @@ private:
{
Context context;
m_success = context.parseElement(m_currentDefinition->filename, xml) && m_success;
- if (m_currentDefinition->firstContextName.isEmpty())
+ if (m_currentDefinition->firstContextName.isEmpty()) {
m_currentDefinition->firstContextName = context.name;
+ }
if (m_currentDefinition->contexts.contains(context.name)) {
qWarning() << m_currentDefinition->filename << "line" << xml.lineNumber() << "duplicate context:" << context.name;
m_success = false;
@@ -784,6 +854,7 @@ private:
m_success = false;
continue;
}
+
if (rule.context.popCount) {
qWarning() << definition.filename << "line" << rule.line << "IncludeRules with #pop prefix";
m_success = false;
@@ -794,6 +865,8 @@ private:
continue;
}
+ // resolve includedRules and includedIncludeRules
+
usedContexts.clear();
usedContexts.insert(rule.context.context);
contexts.clear();
@@ -866,11 +939,27 @@ private:
return usedContexts;
}
+ struct RuleAndInclude {
+ const Context::Rule *rule;
+ const Context::Rule *includeRules;
+
+ explicit operator bool() const
+ {
+ return rule;
+ }
+ };
+
+ struct IncludedRuleUnreachableBy {
+ QVector<RuleAndInclude> unreachableBy;
+ bool alwaysUnreachable = true;
+ };
+
//! Check contexts and rules
bool checkContexts(const Definition &definition,
QSet<const Keywords *> &referencedKeywords,
QSet<ItemDatas::Style> &usedAttributeNames,
- const QSet<const Context *> &usedContexts) const
+ const QSet<const Context *> &usedContexts,
+ QMap<const Context::Rule *, IncludedRuleUnreachableBy> &unreachableIncludedRules) const
{
bool success = true;
@@ -892,16 +981,18 @@ private:
success = false;
}
- if (!context.attribute.isEmpty())
+ if (!context.attribute.isEmpty()) {
usedAttributeNames.insert({context.attribute, context.line});
+ }
success = checkfallthrough(definition, context) && success;
- success = checkUreachableRules(definition.filename, context) && success;
+ success = checkUreachableRules(definition.filename, context, unreachableIncludedRules) && success;
success = suggestRuleMerger(definition.filename, context) && success;
for (const auto &rule : context.rules) {
- if (!rule.attribute.isEmpty())
+ if (!rule.attribute.isEmpty()) {
usedAttributeNames.insert({rule.attribute, rule.line});
+ }
success = checkLookAhead(rule) && success;
success = checkStringDetect(rule) && success;
success = checkAnyChar(rule) && success;
@@ -954,9 +1045,14 @@ private:
return false;
}
+#define REG_ESCAPE_CHAR R"(\\(?:[^0BDPSWbdpswoux]|x[0-9a-fA-F]{2}|x\{[0-9a-fA-F]+\}|0\d\d|o\{[0-7]+\}|u[0-9a-fA-F]{4}))"
+#define REG_CHAR "(?:" REG_ESCAPE_CHAR "|\\[(?:" REG_ESCAPE_CHAR "|.)\\]|[^[.^])"
+
// is RangeDetect
- static const QRegularExpression isRange(QStringLiteral(
- R"(^(\\(?:[^0BDPSWbdpswoux]|x[0-9a-fA-F]{2}|x\{[0-9a-fA-F]+\}|0\d\d|o\{[0-7]+\}|u[0-9a-fA-F]{4})|[^[.]|\[[^].\\]\])(?:\.|\[^\1\])\*[?*]?\1$)"));
+ static const QRegularExpression isRange(QStringLiteral("^\\^?" REG_CHAR "(?:"
+ "\\.\\*[?*]?" REG_CHAR "|"
+ "\\[\\^(" REG_ESCAPE_CHAR "|.)\\]\\*[?*]?\\1"
+ ")$"));
if (( rule.lookAhead == XmlBool::True
|| rule.minimal == XmlBool::True
|| rule.string.contains(QStringLiteral(".*?"))
@@ -967,11 +1063,21 @@ private:
return false;
}
+ // is LineContinue
+ static const QRegularExpression isLineContinue(QStringLiteral("^\\^?" REG_CHAR "\\$$"));
+ if (reg.contains(isLineContinue)) {
+ auto extra = (reg[0] == QLatin1Char('^')) ? "with column=\"0\"" : "";
+ qWarning() << filename << "line" << rule.line << "RegExpr should be replaced by LineContinue:" << rule.string << extra;
+ return false;
+ }
+
// replace \c, \xhhh, \x{hhh...}, \0dd, \o{ddd}, \uhhhh, with _
- static const QRegularExpression sanitize1(
- QStringLiteral(R"(\\(?:[^0BDPSWbdpswoux]|x[0-9a-fA-F]{2}|x\{[0-9a-fA-F]+\}|0\d\d|o\{[0-7]+\}|u[0-9a-fA-F]{4}))"));
+ static const QRegularExpression sanitize1(QStringLiteral(REG_ESCAPE_CHAR));
reg.replace(sanitize1, QStringLiteral("_"));
+#undef REG_CHAR
+#undef REG_ESCAPE_CHAR
+
// use minimal or lazy operator
static const QRegularExpression isMinimal(QStringLiteral(
R"([.][*+][^][?+*()|$]*$)"));
@@ -1008,8 +1114,9 @@ private:
char const *extraMsg = rule.string.contains(QLatin1Char('^')) ? "+ column=\"0\" or firstNonSpace=\"1\"" : "";
qWarning() << rule.filename << "line" << rule.line << "RegExpr should be replaced by StringDetect / Detect2Chars / DetectChar" << extraMsg
<< ":" << rule.string;
- if (len != reg.size())
+ if (len != reg.size()) {
qWarning() << rule.filename << "line" << rule.line << "insensitive=\"1\" missing:" << rule.string;
+ }
return false;
}
@@ -1019,8 +1126,8 @@ private:
// (^sas*) -> ok
// (^sa|s*) -> ko
// (^(sa|s*)) -> ok
- auto first = qAsConst(reg).begin();
- auto last = qAsConst(reg).end();
+ auto first = std::as_const(reg).begin();
+ auto last = std::as_const(reg).end();
int depth = 0;
while (QLatin1Char('(') == *first) {
@@ -1066,8 +1173,8 @@ private:
// add ^ with column=0
if (rule.column == 0 && !rule.isDotRegex) {
bool hasStartOfLine = false;
- auto first = qAsConst(reg).begin();
- auto last = qAsConst(reg).end();
+ auto first = std::as_const(reg).begin();
+ auto last = std::as_const(reg).end();
for (; first != last; ++first) {
if (*first == QLatin1Char('^')) {
hasStartOfLine = true;
@@ -1306,8 +1413,9 @@ private:
//! Search for additionalDeliminator/weakDeliminator which has no effect.
bool checkDelimiters(const Definition &definition, const Context::Rule &rule) const
{
- if (rule.additionalDeliminator.isEmpty() && rule.weakDeliminator.isEmpty())
+ if (rule.additionalDeliminator.isEmpty() && rule.weakDeliminator.isEmpty()) {
return true;
+ }
bool success = true;
@@ -1472,16 +1580,39 @@ private:
//! - StringDetect, WordDetect, RegExpr with as prefix Detect2Chars or other strings
//! - duplicate rule (Int, Float, keyword with same String, etc)
//! - Rule hidden by a dot regex
- bool checkUreachableRules(const QString &filename, const Context &context) const
+ bool checkUreachableRules(const QString &filename,
+ const Context &context,
+ QMap<const Context::Rule *, IncludedRuleUnreachableBy> &unreachableIncludedRules) const
{
- struct RuleAndInclude {
- const Context::Rule *rule;
- const Context::Rule *includeRules;
+ if (context.isOnlyIncluded) {
+ return true;
+ }
- explicit operator bool() const
+ struct Rule4 {
+ RuleAndInclude setRule(const Context::Rule &rule, const Context::Rule *includeRules = nullptr)
{
- return rule;
+ auto set = [&](RuleAndInclude &ruleAndInclude) {
+ auto old = ruleAndInclude;
+ ruleAndInclude = {&rule, includeRules};
+ return old;
+ };
+
+ if (rule.firstNonSpace == XmlBool::True) {
+ return set(firstNonSpace);
+ } else if (rule.column == 0) {
+ return set(column0);
+ } else if (rule.column > 0) {
+ return set(columnGreaterThan0[rule.column]);
+ } else {
+ return set(normal);
+ }
}
+
+ private:
+ RuleAndInclude normal;
+ RuleAndInclude column0;
+ QMap<int, RuleAndInclude> columnGreaterThan0;
+ RuleAndInclude firstNonSpace;
};
// Associate QChar with RuleAndInclude
@@ -1489,8 +1620,9 @@ private:
/// Search RuleAndInclude associated with @p c.
RuleAndInclude find(QChar c) const
{
- if (c.unicode() < 128)
+ if (c.unicode() < 128) {
return m_asciiMap[c.unicode()];
+ }
auto it = m_utf8Map.find(c);
return it == m_utf8Map.end() ? RuleAndInclude{nullptr, nullptr} : it.value();
}
@@ -1517,10 +1649,11 @@ private:
/// Associates @p c with a rule.
void append(QChar c, const Context::Rule &rule, const Context::Rule *includeRule = nullptr)
{
- if (c.unicode() < 128)
+ if (c.unicode() < 128) {
m_asciiMap[c.unicode()] = {&rule, includeRule};
- else
+ } else {
m_utf8Map[c] = {&rule, includeRule};
+ }
}
/// Associates each character of @p s with a rule.
@@ -1549,13 +1682,15 @@ private:
// Char4Tables::char is always added.
CharTableArray(Char4Tables &tables, const Context::Rule &rule)
{
- if (rule.firstNonSpace == XmlBool::True)
+ if (rule.firstNonSpace == XmlBool::True) {
appendTable(tables.charsFirstNonSpace);
+ }
- if (rule.column == 0)
+ if (rule.column == 0) {
appendTable(tables.charsColumn0);
- else if (rule.column > 0)
+ } else if (rule.column > 0) {
appendTable(tables.charsColumnGreaterThan0[rule.column]);
+ }
appendTable(tables.chars);
}
@@ -1572,8 +1707,9 @@ private:
RuleAndInclude find(QChar c) const
{
for (int i = 0; i < m_size; ++i) {
- if (auto ruleAndInclude = m_charTables[i]->find(c))
+ if (auto ruleAndInclude = m_charTables[i]->find(c)) {
return ruleAndInclude;
+ }
}
return RuleAndInclude{nullptr, nullptr};
}
@@ -1621,9 +1757,19 @@ private:
int m_size = 0;
};
+ struct ObservableRule {
+ const Context::Rule *rule;
+ const Context::Rule *includeRules;
+
+ bool hasResolvedIncludeRules() const
+ {
+ return rule == includeRules;
+ }
+ };
+
// Iterates over all the rules, including those in includedRules
struct RuleIterator {
- RuleIterator(const QVector<Context::Rule> &rules, const Context::Rule &endRule)
+ RuleIterator(const QVector<ObservableRule> &rules, const ObservableRule &endRule)
: m_end(&endRule - rules.data())
, m_rules(rules)
{
@@ -1635,7 +1781,7 @@ private:
// if in includedRules
if (m_includedRules) {
++m_i2;
- if (m_i2 != m_rules[m_i].includedRules.size()) {
+ if (m_i2 != m_includedRules->size()) {
return (*m_includedRules)[m_i2];
}
++m_i;
@@ -1643,10 +1789,10 @@ private:
}
// if is a includedRules
- while (m_i < m_end && m_rules[m_i].type == Context::Rule::Type::IncludeRules) {
- if (m_rules[m_i].includedRules.size()) {
+ while (m_i < m_end && m_rules[m_i].rule->type == Context::Rule::Type::IncludeRules) {
+ if (!m_rules[m_i].includeRules && m_rules[m_i].rule->includedRules.size()) {
m_i2 = 0;
- m_includedRules = &m_rules[m_i].includedRules;
+ m_includedRules = &m_rules[m_i].rule->includedRules;
return (*m_includedRules)[m_i2];
}
++m_i;
@@ -1654,7 +1800,7 @@ private:
if (m_i < m_end) {
++m_i;
- return &m_rules[m_i - 1];
+ return m_rules[m_i - 1].rule;
}
return nullptr;
@@ -1663,14 +1809,14 @@ private:
/// \return current IncludeRules or nullptr
const Context::Rule *currentIncludeRules() const
{
- return m_includedRules ? &m_rules[m_i] : nullptr;
+ return m_includedRules ? m_rules[m_i].rule : m_rules[m_i].includeRules;
}
private:
int m_i = 0;
int m_i2;
int m_end;
- const QVector<Context::Rule> &m_rules;
+ const QVector<ObservableRule> &m_rules;
const QVector<const Context::Rule *> *m_includedRules = nullptr;
};
@@ -1680,20 +1826,24 @@ private:
void append(const Context::Rule &rule, const Context::Rule *includedRule)
{
auto array = extractDotRegexes(rule);
- if (array[0])
+ if (array[0]) {
*array[0] = {&rule, includedRule};
- if (array[1])
+ }
+ if (array[1]) {
*array[1] = {&rule, includedRule};
+ }
}
/// Search dot regex which hides @p rule
RuleAndInclude find(const Context::Rule &rule)
{
auto array = extractDotRegexes(rule);
- if (array[0])
+ if (array[0]) {
return *array[0];
- if (array[1])
+ }
+ if (array[1]) {
return *array[1];
+ }
return RuleAndInclude{};
}
@@ -1707,13 +1857,15 @@ private:
if (rule.firstNonSpace != XmlBool::True && rule.column == -1) {
ret[0] = &dotRegex;
} else {
- if (rule.firstNonSpace == XmlBool::True)
+ if (rule.firstNonSpace == XmlBool::True) {
ret[0] = &dotRegexFirstNonSpace;
+ }
- if (rule.column == 0)
+ if (rule.column == 0) {
ret[1] = &dotRegexColumn0;
- else if (rule.column > 0)
+ } else if (rule.column > 0) {
ret[1] = &dotRegexColumnGreaterThan0[rule.column];
+ }
}
return ret;
@@ -1734,23 +1886,44 @@ private:
// characters of LineContinue
Char4Tables lineContinueChars;
- RuleAndInclude intRule{};
- RuleAndInclude floatRule{};
- RuleAndInclude hlCCharRule{};
- RuleAndInclude hlCOctRule{};
- RuleAndInclude hlCHexRule{};
- RuleAndInclude hlCStringCharRule{};
+ Rule4 intRule{};
+ Rule4 floatRule{};
+ Rule4 hlCCharRule{};
+ Rule4 hlCOctRule{};
+ Rule4 hlCHexRule{};
+ Rule4 hlCStringCharRule{};
+ Rule4 detectIdentifierRule{};
// Contains includedRules and included includedRules
QMap<Context const*, RuleAndInclude> includeContexts;
DotRegex dotRegex;
+ QVector<ObservableRule> observedRules;
+ observedRules.reserve(context.rules.size());
for (const Context::Rule &rule : context.rules) {
+ const Context::Rule *includeRule = nullptr;
+ if (rule.type == Context::Rule::Type::IncludeRules) {
+ auto *context = rule.context.context;
+ if (context && context->isOnlyIncluded) {
+ includeRule = &rule;
+ }
+ }
+
+ observedRules.push_back({&rule, includeRule});
+ if (includeRule) {
+ for (const Context::Rule *rule2 : rule.includedRules) {
+ observedRules.push_back({rule2, includeRule});
+ }
+ }
+ }
+
+ for (auto &observedRule : observedRules) {
+ const Context::Rule &rule = *observedRule.rule;
bool isUnreachable = false;
QVector<RuleAndInclude> unreachableBy;
- // declare rule as unreacheable if ruleAndInclude is not empty
+ // declare rule as unreachable if ruleAndInclude is not empty
auto updateUnreachable1 = [&](RuleAndInclude ruleAndInclude) {
if (ruleAndInclude) {
isUnreachable = true;
@@ -1758,7 +1931,7 @@ private:
}
};
- // declare rule as unreacheable if ruleAndIncludes is not empty
+ // declare rule as unreachable if ruleAndIncludes is not empty
auto updateUnreachable2 = [&](const QVector<RuleAndInclude> &ruleAndIncludes) {
if (!ruleAndIncludes.isEmpty()) {
isUnreachable = true;
@@ -1810,43 +1983,42 @@ private:
// check if hidden by DetectChar/AnyChar
case Context::Rule::Type::HlCChar:
updateUnreachable1(CharTableArray(detectChars, rule).find(QLatin1Char('\'')));
- updateUnreachable1(hlCCharRule);
- hlCCharRule = {&rule, nullptr};
+ updateUnreachable1(hlCCharRule.setRule(rule));
break;
// check if hidden by DetectChar/AnyChar
case Context::Rule::Type::HlCHex:
updateUnreachable1(CharTableArray(detectChars, rule).find(QLatin1Char('0')));
- updateUnreachable1(hlCHexRule);
- hlCHexRule = {&rule, nullptr};
+ updateUnreachable1(hlCHexRule.setRule(rule));
break;
// check if hidden by DetectChar/AnyChar
case Context::Rule::Type::HlCOct:
updateUnreachable1(CharTableArray(detectChars, rule).find(QLatin1Char('0')));
- updateUnreachable1(hlCOctRule);
- hlCOctRule = {&rule, nullptr};
+ updateUnreachable1(hlCOctRule.setRule(rule));
break;
// check if hidden by DetectChar/AnyChar
case Context::Rule::Type::HlCStringChar:
updateUnreachable1(CharTableArray(detectChars, rule).find(QLatin1Char('\\')));
- updateUnreachable1(hlCStringCharRule);
- hlCStringCharRule = {&rule, nullptr};
+ updateUnreachable1(hlCStringCharRule.setRule(rule));
break;
// check if hidden by DetectChar/AnyChar
case Context::Rule::Type::Int:
updateUnreachable2(CharTableArray(detectChars, rule).find(QStringLiteral("0123456789")));
- updateUnreachable1(intRule);
- intRule = {&rule, nullptr};
+ updateUnreachable1(intRule.setRule(rule));
break;
// check if hidden by DetectChar/AnyChar
case Context::Rule::Type::Float:
updateUnreachable2(CharTableArray(detectChars, rule).find(QStringLiteral("0123456789.")));
- updateUnreachable1(floatRule);
- floatRule = {&rule, nullptr};
+ updateUnreachable1(floatRule.setRule(rule));
+ break;
+
+ // check if hidden by another DetectIdentifier rule
+ case Context::Rule::Type::DetectIdentifier:
+ updateUnreachable1(detectIdentifierRule.setRule(rule));
break;
// check if hidden by DetectChar/AnyChar or another LineContinue
@@ -1865,10 +2037,11 @@ private:
case Context::Rule::Type::RangeDetect:
updateUnreachable1(CharTableArray(detectChars, rule).find(rule.char0));
if (!isUnreachable) {
- RuleIterator ruleIterator(context.rules, rule);
+ RuleIterator ruleIterator(observedRules, observedRule);
while (const auto *rulePtr = ruleIterator.next()) {
- if (isUnreachable)
+ if (isUnreachable) {
break;
+ }
const auto &rule2 = *rulePtr;
if (rule2.type == rule.type && isCompatible(rule2) && rule.char0 == rule2.char0 && rule.char1 == rule2.char1) {
updateUnreachable1({&rule2, ruleIterator.currentIncludeRules()});
@@ -1884,10 +2057,11 @@ private:
}
// check that `rule` does not have another RegExpr as a prefix
- RuleIterator ruleIterator(context.rules, rule);
+ RuleIterator ruleIterator(observedRules, observedRule);
while (const auto *rulePtr = ruleIterator.next()) {
- if (isUnreachable)
+ if (isUnreachable) {
break;
+ }
const auto &rule2 = *rulePtr;
if (rule2.type == Context::Rule::Type::RegExpr && isCompatible(rule2) && rule.insensitive == rule2.insensitive
&& rule.dynamic == rule2.dynamic && rule.string.startsWith(rule2.string)) {
@@ -1902,10 +2076,11 @@ private:
case Context::Rule::Type::StringDetect: {
// check that dynamic `rule` does not have another dynamic StringDetect as a prefix
if (rule.type == Context::Rule::Type::StringDetect && rule.dynamic == XmlBool::True) {
- RuleIterator ruleIterator(context.rules, rule);
+ RuleIterator ruleIterator(observedRules, observedRule);
while (const auto *rulePtr = ruleIterator.next()) {
- if (isUnreachable)
+ if (isUnreachable) {
break;
+ }
const auto &rule2 = *rulePtr;
if (rule2.type != Context::Rule::Type::StringDetect || rule2.dynamic != XmlBool::True || !isCompatible(rule2)) {
@@ -1963,10 +2138,11 @@ private:
// combination of uppercase and lowercase
RuleAndInclude detect2CharsInsensitives[]{{}, {}, {}, {}};
- RuleIterator ruleIterator(context.rules, rule);
+ RuleIterator ruleIterator(observedRules, observedRule);
while (const auto *rulePtr = ruleIterator.next()) {
- if (isUnreachable)
+ if (isUnreachable) {
break;
+ }
const auto &rule2 = *rulePtr;
const bool isSensitive = (rule2.insensitive == XmlBool::True);
const auto caseSensitivity = isSensitive ? Qt::CaseInsensitive : Qt::CaseSensitive;
@@ -2030,10 +2206,11 @@ private:
// check if hidden by another keyword rule
case Context::Rule::Type::keyword: {
- RuleIterator ruleIterator(context.rules, rule);
+ RuleIterator ruleIterator(observedRules, observedRule);
while (const auto *rulePtr = ruleIterator.next()) {
- if (isUnreachable)
+ if (isUnreachable) {
break;
+ }
const auto &rule2 = *rulePtr;
if (rule2.type == Context::Rule::Type::keyword && isCompatible(rule2) && rule.string == rule2.string) {
updateUnreachable1({&rule2, ruleIterator.currentIncludeRules()});
@@ -2049,6 +2226,10 @@ private:
// <includedRules .../> <- reference a <DetectChar char="{" /> who will be added
// <DetectChar char="{" /> <- hidden by previous rule
case Context::Rule::Type::IncludeRules:
+ if (observedRule.includeRules && !observedRule.hasResolvedIncludeRules()) {
+ break;
+ }
+
if (auto &ruleAndInclude = includeContexts[rule.context.context]) {
updateUnreachable1(ruleAndInclude);
}
@@ -2060,6 +2241,10 @@ private:
includeContexts.insert(rulePtr->context.context, RuleAndInclude{rulePtr, &rule});
}
+ if (observedRule.includeRules) {
+ break;
+ }
+
for (const auto *rulePtr : rule.includedRules) {
const auto &rule2 = *rulePtr;
switch (rule2.type) {
@@ -2087,27 +2272,27 @@ private:
}
case Context::Rule::Type::HlCChar:
- hlCCharRule = {&rule2, &rule};
+ hlCCharRule.setRule(rule2, &rule);
break;
case Context::Rule::Type::HlCHex:
- hlCHexRule = {&rule2, &rule};
+ hlCHexRule.setRule(rule2, &rule);
break;
case Context::Rule::Type::HlCOct:
- hlCOctRule = {&rule2, &rule};
+ hlCOctRule.setRule(rule2, &rule);
break;
case Context::Rule::Type::HlCStringChar:
- hlCStringCharRule = {&rule2, &rule};
+ hlCStringCharRule.setRule(rule2, &rule);
break;
case Context::Rule::Type::Int:
- intRule = {&rule2, &rule};
+ intRule.setRule(rule2, &rule);
break;
case Context::Rule::Type::Float:
- floatRule = {&rule2, &rule};
+ floatRule.setRule(rule2, &rule);
break;
case Context::Rule::Type::LineContinue: {
@@ -2136,12 +2321,18 @@ private:
}
break;
- case Context::Rule::Type::DetectIdentifier:
case Context::Rule::Type::Unknown:
break;
}
- if (isUnreachable) {
+ if (observedRule.includeRules && !observedRule.hasResolvedIncludeRules()) {
+ auto &unreachableIncludedRule = unreachableIncludedRules[&rule];
+ if (isUnreachable && unreachableIncludedRule.alwaysUnreachable) {
+ unreachableIncludedRule.unreachableBy.append(unreachableBy);
+ } else {
+ unreachableIncludedRule.alwaysUnreachable = false;
+ }
+ } else if (isUnreachable) {
success = false;
QString message;
message.reserve(128);
@@ -2165,7 +2356,7 @@ private:
message += QStringLiteral(", ");
}
message.chop(2);
- qWarning() << filename << "line" << rule.line << "unreachable element by" << message;
+ qWarning() << filename << "line" << rule.line << "unreachable rule by" << message;
}
}
@@ -2179,8 +2370,9 @@ private:
{
bool success = true;
- if (context.rules.isEmpty())
+ if (context.rules.isEmpty()) {
return success;
+ }
auto it = context.rules.begin();
const auto end = context.rules.end() - 1;
@@ -2249,7 +2441,7 @@ private:
//! - "#pop!Comment" -> "Comment"
//! - "##ISO C++" -> ""
//! - "Comment##ISO C++"-> "Comment" in ISO C++
- void resolveContextName(Definition &definition, const Context &context, ContextName &contextName, int line)
+ void resolveContextName(Definition &definition, Context &context, ContextName &contextName, int line)
{
QString name = contextName.name;
if (name.isEmpty()) {
@@ -2281,8 +2473,9 @@ private:
const int idx = name.indexOf(QStringLiteral("##"));
if (idx == -1) {
auto it = definition.contexts.find(name);
- if (it != definition.contexts.end())
+ if (it != definition.contexts.end()) {
contextName.context = &*it;
+ }
} else {
auto defName = name.mid(idx + 2);
auto listName = name.left(idx);
@@ -2392,14 +2585,16 @@ int main(int argc, char *argv[])
QCoreApplication app(argc, argv);
// ensure enough arguments are passed
- if (app.arguments().size() < 3)
+ if (app.arguments().size() < 3) {
return 1;
+ }
#ifdef QT_XMLPATTERNS_LIB
// open schema
QXmlSchema schema;
- if (!schema.load(QUrl::fromLocalFile(app.arguments().at(2))))
+ if (!schema.load(QUrl::fromLocalFile(app.arguments().at(2)))) {
return 2;
+ }
#endif
const QString hlFilenamesListing = app.arguments().value(3);
@@ -2422,7 +2617,7 @@ int main(int argc, char *argv[])
HlFilesChecker filesChecker;
QVariantMap hls;
int anyError = 0;
- for (const QString &hlFilename : qAsConst(hlFilenames)) {
+ for (const QString &hlFilename : std::as_const(hlFilenames)) {
QFile hlFile(hlFilename);
if (!hlFile.open(QIODevice::ReadOnly)) {
qWarning("Failed to open %s", qPrintable(hlFilename));
@@ -2456,7 +2651,7 @@ int main(int argc, char *argv[])
QVariantMap hl;
// transfer text attributes
- for (const QString &attribute : qAsConst(textAttributes)) {
+ for (const QString &attribute : std::as_const(textAttributes)) {
hl[attribute] = xml.attributes().value(attribute).toString();
}
@@ -2489,17 +2684,20 @@ int main(int argc, char *argv[])
filesChecker.resolveContexts();
- if (!filesChecker.check())
+ if (!filesChecker.check()) {
anyError = 7;
+ }
// bail out if any problem was seen
- if (anyError)
+ if (anyError) {
return anyError;
+ }
// create outfile, after all has worked!
QFile outFile(app.arguments().at(1));
- if (!outFile.open(QIODevice::WriteOnly | QIODevice::Truncate))
+ if (!outFile.open(QIODevice::WriteOnly | QIODevice::Truncate)) {
return 9;
+ }
// write out json
outFile.write(QCborValue::fromVariant(QVariant(hls)).toCbor());
diff --git a/src/libs/3rdparty/syntax-highlighting/src/lib/CMakeLists.txt b/src/libs/3rdparty/syntax-highlighting/src/lib/CMakeLists.txt
index 722f92742b..43a60cc19b 100644
--- a/src/libs/3rdparty/syntax-highlighting/src/lib/CMakeLists.txt
+++ b/src/libs/3rdparty/syntax-highlighting/src/lib/CMakeLists.txt
@@ -1,6 +1,8 @@
+add_library(KF5SyntaxHighlighting)
+
ecm_create_qm_loader(syntax_highlighting_QM_LOADER syntaxhighlighting5_qt)
-set(syntax_highlighting_srcs
+target_sources(KF5SyntaxHighlighting PRIVATE
abstracthighlighter.cpp
context.cpp
contextswitch.cpp
@@ -20,8 +22,9 @@ set(syntax_highlighting_srcs
themedata.cpp
worddelimiters.cpp
${syntax_highlighting_QM_LOADER}
+ $<TARGET_OBJECTS:SyntaxHighlightingData>
)
-ecm_qt_declare_logging_category(syntax_highlighting_srcs
+ecm_qt_declare_logging_category(KF5SyntaxHighlighting
HEADER ksyntaxhighlighting_logging.h
IDENTIFIER KSyntaxHighlighting::Log
CATEGORY_NAME kf.syntaxhighlighting
@@ -30,16 +33,27 @@ ecm_qt_declare_logging_category(syntax_highlighting_srcs
EXPORT KSYNTAXHIGHLIGHTING
)
-add_library(KF5SyntaxHighlighting ${syntax_highlighting_srcs} $<TARGET_OBJECTS:SyntaxHighlightingData>)
-generate_export_header(KF5SyntaxHighlighting BASE_NAME KSyntaxHighlighting)
+ecm_generate_export_header(KF5SyntaxHighlighting
+ BASE_NAME KSyntaxHighlighting
+ GROUP_BASE_NAME KF
+ VERSION ${KF_VERSION}
+ DEPRECATED_BASE_VERSION 0
+ DEPRECATION_VERSIONS 5.87
+ EXCLUDE_DEPRECATED_BEFORE_AND_AT ${EXCLUDE_DEPRECATED_BEFORE_AND_AT}
+)
set_target_properties(KF5SyntaxHighlighting PROPERTIES
- VERSION ${SyntaxHighlighting_VERSION_STRING}
+ VERSION ${SyntaxHighlighting_VERSION}
SOVERSION ${SyntaxHighlighting_SOVERSION}
EXPORT_NAME SyntaxHighlighting
)
target_include_directories(KF5SyntaxHighlighting INTERFACE "$<INSTALL_INTERFACE:${KDE_INSTALL_INCLUDEDIR_KF5}/KSyntaxHighlighting;${KDE_INSTALL_INCLUDEDIR_KF5}>")
target_include_directories(KF5SyntaxHighlighting PUBLIC "$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR};${CMAKE_CURRENT_BINARY_DIR};>")
-target_link_libraries(KF5SyntaxHighlighting LINK_PUBLIC Qt5::Gui LINK_PRIVATE Qt5::Network)
+target_link_libraries(KF5SyntaxHighlighting
+ PUBLIC
+ Qt5::Gui
+ PRIVATE
+ Qt5::Network
+)
ecm_generate_headers(SyntaxHighlighting_HEADERS
HEADER_NAMES
@@ -52,6 +66,7 @@ ecm_generate_headers(SyntaxHighlighting_HEADERS
State
SyntaxHighlighter
Theme
+ WildcardMatcher
REQUIRED_HEADERS SyntaxHighlighting_HEADERS
)
diff --git a/src/libs/3rdparty/syntax-highlighting/src/lib/abstracthighlighter.cpp b/src/libs/3rdparty/syntax-highlighting/src/lib/abstracthighlighter.cpp
index 2ad9d371f9..d6f8cad0c7 100644
--- a/src/libs/3rdparty/syntax-highlighting/src/lib/abstracthighlighter.cpp
+++ b/src/libs/3rdparty/syntax-highlighting/src/lib/abstracthighlighter.cpp
@@ -36,11 +36,13 @@ void AbstractHighlighterPrivate::ensureDefinitionLoaded()
defData = DefinitionData::get(m_definition);
}
- if (Q_UNLIKELY(!defData->repo && !defData->fileName.isEmpty()))
+ if (Q_UNLIKELY(!defData->repo && !defData->fileName.isEmpty())) {
qCCritical(Log) << "Repository got deleted while a highlighter is still active!";
+ }
- if (m_definition.isValid())
+ if (m_definition.isValid()) {
defData->load();
+ }
}
AbstractHighlighter::AbstractHighlighter()
@@ -85,7 +87,7 @@ void AbstractHighlighter::setTheme(const Theme &theme)
* Returns the index of the first non-space character. If the line is empty,
* or only contains white spaces, text.size() is returned.
*/
-static inline int firstNonSpaceChar(const QString &text)
+static inline int firstNonSpaceChar(QStringView text)
{
for (int i = 0; i < text.length(); ++i) {
if (!text[i].isSpace()) {
@@ -95,8 +97,15 @@ static inline int firstNonSpaceChar(const QString &text)
return text.size();
}
+#if KSYNTAXHIGHLIGHTING_BUILD_DEPRECATED_SINCE(5, 87)
State AbstractHighlighter::highlightLine(const QString &text, const State &state)
{
+ return highlightLine(QStringView(text), state);
+}
+#endif
+
+State AbstractHighlighter::highlightLine(QStringView text, const State &state)
+{
Q_D(AbstractHighlighter);
// verify definition, deal with no highlighting being enabled
@@ -145,8 +154,9 @@ State AbstractHighlighter::highlightLine(const QString &text, const State &state
* skipping empty lines after a line continuation character (see bug 405903)
*/
} else if (!stateData->topContext()->lineEndContext().isStay()
- && !d->switchContext(stateData, stateData->topContext()->lineEndContext(), QStringList()))
+ && !d->switchContext(stateData, stateData->topContext()->lineEndContext(), QStringList())) {
break;
+ }
// guard against endless loops
++endlessLoopingCounter;
@@ -160,7 +170,8 @@ State AbstractHighlighter::highlightLine(const QString &text, const State &state
return newState;
}
- int offset = 0, beginOffset = 0;
+ int offset = 0;
+ int beginOffset = 0;
bool lineContinuation = false;
/**
@@ -247,8 +258,9 @@ State AbstractHighlighter::highlightLine(const QString &text, const State &state
skipOffsets.clear();
}
const auto currentSkipOffset = skipOffsets.value(rule.get());
- if (currentSkipOffset < 0 || currentSkipOffset > offset)
+ if (currentSkipOffset < 0 || currentSkipOffset > offset) {
continue;
+ }
const auto newResult = rule->doMatch(text, offset, stateData->topCaptures());
newOffset = newResult.offset();
@@ -265,8 +277,9 @@ State AbstractHighlighter::highlightLine(const QString &text, const State &state
}
}
- if (newOffset <= offset)
+ if (newOffset <= offset) {
continue;
+ }
/**
* apply folding.
@@ -274,12 +287,14 @@ State AbstractHighlighter::highlightLine(const QString &text, const State &state
* - rule with endRegion + beginRegion: in endRegion, the length is 0
* - rule with lookAhead: length is 0
*/
- if (rule->endRegion().isValid() && rule->beginRegion().isValid())
+ if (rule->endRegion().isValid() && rule->beginRegion().isValid()) {
applyFolding(offset, 0, rule->endRegion());
- else if (rule->endRegion().isValid())
+ } else if (rule->endRegion().isValid()) {
applyFolding(offset, rule->isLookAhead() ? 0 : newOffset - offset, rule->endRegion());
- if (rule->beginRegion().isValid())
+ }
+ if (rule->beginRegion().isValid()) {
applyFolding(offset, rule->isLookAhead() ? 0 : newOffset - offset, rule->beginRegion());
+ }
if (rule->isLookAhead()) {
Q_ASSERT(!rule->context().isStay());
@@ -290,12 +305,14 @@ State AbstractHighlighter::highlightLine(const QString &text, const State &state
d->switchContext(stateData, rule->context(), newResult.captures());
newFormat = rule->attributeFormat().isValid() ? &rule->attributeFormat() : &stateData->topContext()->attributeFormat();
- if (newOffset == text.size() && std::dynamic_pointer_cast<LineContinue>(rule))
+ if (newOffset == text.size() && std::dynamic_pointer_cast<LineContinue>(rule)) {
lineContinuation = true;
+ }
break;
}
- if (isLookAhead)
+ if (isLookAhead) {
continue;
+ }
if (newOffset <= offset) { // no matching rule
if (stateData->topContext()->fallthrough()) {
@@ -316,8 +333,9 @@ State AbstractHighlighter::highlightLine(const QString &text, const State &state
* on format change, apply the last one and switch to new one
*/
if (newFormat != currentFormat && newFormat->id() != currentFormat->id()) {
- if (offset > 0)
+ if (offset > 0) {
applyFormat(beginOffset, offset - beginOffset, *currentFormat);
+ }
beginOffset = offset;
currentFormat = newFormat;
}
@@ -333,8 +351,9 @@ State AbstractHighlighter::highlightLine(const QString &text, const State &state
/**
* apply format for remaining text, if any
*/
- if (beginOffset < offset)
+ if (beginOffset < offset) {
applyFormat(beginOffset, text.size() - beginOffset, *currentFormat);
+ }
/**
* handle line end context switches
@@ -344,8 +363,9 @@ State AbstractHighlighter::highlightLine(const QString &text, const State &state
{
int endlessLoopingCounter = 0;
while (!stateData->topContext()->lineEndContext().isStay() && !lineContinuation) {
- if (!d->switchContext(stateData, stateData->topContext()->lineEndContext(), QStringList()))
+ if (!d->switchContext(stateData, stateData->topContext()->lineEndContext(), QStringList())) {
break;
+ }
// guard against endless loops
++endlessLoopingCounter;
diff --git a/src/libs/3rdparty/syntax-highlighting/src/lib/abstracthighlighter.h b/src/libs/3rdparty/syntax-highlighting/src/lib/abstracthighlighter.h
index 5e85873ce0..49cfbf2530 100644
--- a/src/libs/3rdparty/syntax-highlighting/src/lib/abstracthighlighter.h
+++ b/src/libs/3rdparty/syntax-highlighting/src/lib/abstracthighlighter.h
@@ -108,6 +108,15 @@ protected:
AbstractHighlighter();
AbstractHighlighter(AbstractHighlighterPrivate *dd);
+#if KSYNTAXHIGHLIGHTING_ENABLE_DEPRECATED_SINCE(5, 87)
+ /**
+ * @copydoc highlightLine(QStringView,const State&)
+ * @deprecated since 5.87, use highlightLine(QStringView, const State&) instead.
+ */
+ // no deprecation warning, as removal of this will automatically "port" the using code
+ State highlightLine(const QString &text, const State &state);
+#endif
+
// TODO KF6: add an optional void* context argument that is passed through
// to the applyX() calls, so highlighters dealing with some form of line object
// (such as QSyntaxHighlighter or KTextEditor) can avoid some ugly hacks to have
@@ -120,14 +129,14 @@ protected:
* @param state The highlighting state handle returned by the call
* to highlightLine() for the previous line. For the very first line,
* just pass a default constructed State().
- * @returns The state of the highlighing engine after processing the
+ * @returns The state of the highlighting engine after processing the
* given line. This needs to passed into highlightLine() for the
* next line. You can store the state for efficient partial
* re-highlighting for example during editing.
*
* @see applyFormat(), applyFolding()
*/
- State highlightLine(const QString &text, const State &state);
+ State highlightLine(QStringView text, const State &state);
/**
* Reimplement this to apply formats to your output. The provided @p format
diff --git a/src/libs/3rdparty/syntax-highlighting/src/lib/ansihighlighter.cpp b/src/libs/3rdparty/syntax-highlighting/src/lib/ansihighlighter.cpp
index 9ff012e1d7..8ae47d80eb 100644
--- a/src/libs/3rdparty/syntax-highlighting/src/lib/ansihighlighter.cpp
+++ b/src/libs/3rdparty/syntax-highlighting/src/lib/ansihighlighter.cpp
@@ -33,10 +33,6 @@ struct CieLab {
double b;
};
-#ifndef M_PI
-constexpr double M_PI = 3.14159265358979323846;
-#endif
-
// clang-format off
// xterm color reference
// constexpr Rgb888 xterm256Colors[] {
@@ -388,10 +384,11 @@ CieLab rgbToLab(QRgb rgb)
// Perform the inverse gamma companding for a sRGB color
// http://www.brucelindbloom.com/index.html?Eqn_RGB_to_XYZ.html
auto inverseGammaCompanding = [](int c) {
- if (c <= 10)
+ if (c <= 10) {
return c / (255.0 * 12.92);
- else
+ } else {
return std::pow((c / 255.0 + 0.055) / 1.055, 2.4);
+ }
};
const double r = inverseGammaCompanding(qRed(rgb));
@@ -404,10 +401,11 @@ CieLab rgbToLab(QRgb rgb)
// http://www.brucelindbloom.com/index.html?Eqn_XYZ_to_Lab.html
auto f = [](double t) {
- if (t > 216.0 / 24389.0)
+ if (t > 216.0 / 24389.0) {
return std::cbrt(t);
- else
+ } else {
return t * (24389.0 / (27.0 * 116.0)) + 4.0 / 29.0;
+ }
};
const double f_x = f(x / illuminant_D65[0]);
@@ -440,8 +438,9 @@ inline double pow2(double x)
inline double computeHPrime(double a_prime, double b)
{
- if (std::abs(a_prime) < epsilon && std::abs(b) < epsilon)
+ if (std::abs(a_prime) < epsilon && std::abs(b) < epsilon) {
return 0.0;
+ }
const double value = std::atan2(b, a_prime) * 180.0 / M_PI;
return (value < 0.0) ? value + 360.0 : value;
@@ -449,34 +448,38 @@ inline double computeHPrime(double a_prime, double b)
inline double computeDeltaHPrime(double C1_prime, double C2_prime, double h1_prime, double h2_prime)
{
- if (C1_prime * C2_prime < epsilon)
+ if (C1_prime * C2_prime < epsilon) {
return 0.0;
+ }
const double diff = h2_prime - h1_prime;
- if (std::abs(diff) <= 180.0)
+ if (std::abs(diff) <= 180.0) {
return diff;
- else if (diff > 180.0)
+ } else if (diff > 180.0) {
return diff - 360.0;
- else
+ } else {
return diff + 360.0;
+ }
}
inline double computeHPrimeBar(double C1_prime, double C2_prime, double h1_prime, double h2_prime)
{
const double sum = h1_prime + h2_prime;
- if (C1_prime * C2_prime < epsilon)
+ if (C1_prime * C2_prime < epsilon) {
return sum;
+ }
const double dist = std::abs(h1_prime - h2_prime);
- if (dist <= 180.0)
+ if (dist <= 180.0) {
return 0.5 * sum;
- else if (sum < 360.0)
+ } else if (sum < 360.0) {
return 0.5 * (sum + 360.0);
- else
+ } else {
return 0.5 * (sum - 360.0);
+ }
}
/// Calculate the perceptual color difference based on CIEDE2000.
@@ -702,7 +705,7 @@ struct GraphLine {
const int n2 = offset - labelLineLength;
labelLineLength += n2 + 1;
fillLine(labelLine, n2);
- labelLine += graphLine.rightRef(graphLine.size() - ps1);
+ labelLine += QStringView(graphLine).right(graphLine.size() - ps1);
}
}
@@ -781,8 +784,9 @@ public:
state = highlightLine(currentLine, state);
if (hasSeparator) {
- if (!firstLine)
+ if (!firstLine) {
out << QStringLiteral("\x1b[0m────────────────────────────────────────────────────\x1b[K\n");
+ }
firstLine = false;
}
@@ -793,14 +797,15 @@ public:
for (const auto &fragment : m_highlightedFragments) {
auto const &ansiStyle = ansiStyles[fragment.formatId];
- out << ansiStyle.first << currentLine.midRef(fragment.offset, fragment.length) << ansiStyle.second;
+ out << ansiStyle.first << QStringView(currentLine).mid(fragment.offset, fragment.length) << ansiStyle.second;
}
out << QStringLiteral("\x1b[K\n");
if (hasFormatOrContextTrace && !m_highlightedFragments.empty()) {
- if (m_hasContextTrace || m_hasStackSizeTrace)
+ if (m_hasContextTrace || m_hasStackSizeTrace) {
appendContextNames(oldState, currentLine);
+ }
printFormats(out, infoStyle, ansiStyles);
out << resetBgColor;
@@ -817,8 +822,9 @@ public:
void applyFolding(int offset, int /*length*/, FoldingRegion region) override
{
- if (!m_hasRegionTrace)
+ if (!m_hasRegionTrace) {
return;
+ }
const auto id = region.id();
@@ -829,8 +835,9 @@ public:
auto &previousRegion = m_regions[m_regions.size() - 2];
if (previousRegion.state == Region::State::Close && previousRegion.offset == offset) {
std::swap(previousRegion, m_regions.back());
- if (previousRegion.bindIndex != -1)
+ if (previousRegion.bindIndex != -1) {
m_regions[previousRegion.bindIndex].bindIndex = m_regions.size() - 1;
+ }
}
}
++m_regionDepth;
@@ -840,10 +847,11 @@ public:
auto eit = m_regions.rend();
for (int depth = 0; it != eit; ++it) {
if (it->regionId == id && it->bindIndex < 0) {
- if (it->state == Region::State::Close)
+ if (it->state == Region::State::Close) {
++depth;
- else if (--depth < 0)
+ } else if (--depth < 0) {
break;
+ }
}
}
@@ -868,8 +876,9 @@ private:
void initRegionStyles(const std::vector<QPair<QString, QString>> &ansiStyles)
{
m_regionStyles.resize(ansiStyles.size());
- for (std::size_t i = 0; i < m_regionStyles.size(); ++i)
+ for (std::size_t i = 0; i < m_regionStyles.size(); ++i) {
m_regionStyles[i] = ansiStyles[i].first;
+ }
std::sort(m_regionStyles.begin(), m_regionStyles.end());
m_regionStyles.erase(std::unique(m_regionStyles.begin(), m_regionStyles.end()), m_regionStyles.end());
@@ -1216,7 +1225,7 @@ void AnsiHighlighter::highlightData(QIODevice *dev, AnsiFormat format, bool useE
}
// initialize ansiStyles
- for (auto &&definition : qAsConst(definitions)) {
+ for (auto &&definition : std::as_const(definitions)) {
const auto formats = definition.formats();
for (auto &&format : formats) {
const auto id = format.id();
@@ -1236,20 +1245,26 @@ void AnsiHighlighter::highlightData(QIODevice *dev, AnsiFormat format, bool useE
const bool hasUnderline = format.isUnderline(theme);
const bool hasStrikeThrough = format.isStrikeThrough(theme);
- if (hasFg)
+ if (hasFg) {
buffer.appendForeground(format.textColor(theme).rgb(), is256Colors, colorCache);
- else
+ } else {
buffer.append(foregroundDefaultColor);
- if (hasBg)
+ }
+ if (hasBg) {
buffer.appendBackground(format.backgroundColor(theme).rgb(), is256Colors, colorCache);
- if (hasBold)
+ }
+ if (hasBold) {
buffer.append(QLatin1String("1;"));
- if (hasItalic)
+ }
+ if (hasItalic) {
buffer.append(QLatin1String("3;"));
- if (hasUnderline)
+ }
+ if (hasUnderline) {
buffer.append(QLatin1String("4;"));
- if (hasStrikeThrough)
+ }
+ if (hasStrikeThrough) {
buffer.append(QLatin1String("9;"));
+ }
// if there is ANSI style
if (buffer.latin1().size() > 2) {
@@ -1266,14 +1281,18 @@ void AnsiHighlighter::highlightData(QIODevice *dev, AnsiFormat format, bool useE
d->ansiStyles[id].second = buffer.latin1();
} else if (hasEffect) {
buffer.append(QLatin1String("\x1b["));
- if (hasBold)
+ if (hasBold) {
buffer.append(QLatin1String("21;"));
- if (hasItalic)
+ }
+ if (hasItalic) {
buffer.append(QLatin1String("23;"));
- if (hasUnderline)
+ }
+ if (hasUnderline) {
buffer.append(QLatin1String("24;"));
- if (hasStrikeThrough)
+ }
+ if (hasStrikeThrough) {
buffer.append(QLatin1String("29;"));
+ }
buffer.setFinalStyle();
d->ansiStyles[id].second = buffer.latin1();
}
@@ -1301,10 +1320,11 @@ void AnsiHighlighter::highlightData(QIODevice *dev, AnsiFormat format, bool useE
d->currentLine = in.readLine();
state = highlightLine(d->currentLine, state);
- if (useEditorBackground)
+ if (useEditorBackground) {
d->out << QStringLiteral("\x1b[K\n");
- else
+ } else {
d->out << QLatin1Char('\n');
+ }
}
} else {
AnsiBuffer buffer;
@@ -1328,5 +1348,5 @@ void AnsiHighlighter::highlightData(QIODevice *dev, AnsiFormat format, bool useE
void AnsiHighlighter::applyFormat(int offset, int length, const Format &format)
{
auto const &ansiStyle = d->ansiStyles[format.id()];
- d->out << ansiStyle.first << d->currentLine.midRef(offset, length) << ansiStyle.second;
+ d->out << ansiStyle.first << QStringView(d->currentLine).mid(offset, length) << ansiStyle.second;
}
diff --git a/src/libs/3rdparty/syntax-highlighting/src/lib/context.cpp b/src/libs/3rdparty/syntax-highlighting/src/lib/context.cpp
index f980ea5be8..724f37a03f 100644
--- a/src/libs/3rdparty/syntax-highlighting/src/lib/context.cpp
+++ b/src/libs/3rdparty/syntax-highlighting/src/lib/context.cpp
@@ -30,8 +30,9 @@ void Context::setDefinition(const DefinitionRef &def)
bool Context::indentationBasedFoldingEnabled() const
{
- if (m_noIndentationBasedFolding)
+ if (m_noIndentationBasedFolding) {
return false;
+ }
return m_def.definition().indentationBasedFoldingEnabled();
}
@@ -56,8 +57,9 @@ void Context::load(QXmlStreamReader &reader)
auto rule = Rule::create(reader.name());
if (rule) {
rule->setDefinition(m_def.definition());
- if (rule->load(reader))
+ if (rule->load(reader)) {
m_rules.push_back(std::move(rule));
+ }
} else {
reader.skipCurrentElement();
}
@@ -79,8 +81,9 @@ void Context::resolveContexts()
m_lineEndContext.resolve(def);
m_lineEmptyContext.resolve(def);
m_fallthroughContext.resolve(def);
- for (const auto &rule : m_rules)
+ for (const auto &rule : m_rules) {
rule->resolveContext();
+ }
}
Context::ResolveState Context::resolveState()
@@ -100,8 +103,9 @@ Context::ResolveState Context::resolveState()
void Context::resolveIncludes()
{
- if (resolveState() == Resolved)
+ if (resolveState() == Resolved) {
return;
+ }
if (resolveState() == Resolving) {
qCWarning(Log) << "Cyclic dependency!";
return;
@@ -129,10 +133,11 @@ void Context::resolveIncludes()
}
auto defData = DefinitionData::get(def);
defData->load();
- if (inc->contextName().isEmpty())
+ if (inc->contextName().isEmpty()) {
context = defData->initialContext();
- else
+ } else {
context = defData->contextByName(inc->contextName());
+ }
}
if (!context) {
qCWarning(Log) << "Unable to resolve include rule for definition" << inc->contextName() << "##" << inc->definitionName() << "in"
diff --git a/src/libs/3rdparty/syntax-highlighting/src/lib/contextswitch.cpp b/src/libs/3rdparty/syntax-highlighting/src/lib/contextswitch.cpp
index 7ccd73ee9b..e829af463a 100644
--- a/src/libs/3rdparty/syntax-highlighting/src/lib/contextswitch.cpp
+++ b/src/libs/3rdparty/syntax-highlighting/src/lib/contextswitch.cpp
@@ -29,8 +29,9 @@ Context *ContextSwitch::context() const
void ContextSwitch::parse(QStringView contextInstr)
{
- if (contextInstr.isEmpty() || contextInstr == QLatin1String("#stay"))
+ if (contextInstr.isEmpty() || contextInstr == QLatin1String("#stay")) {
return;
+ }
if (contextInstr.startsWith(QLatin1String("#pop!"))) {
++m_popCount;
@@ -60,13 +61,15 @@ void ContextSwitch::resolve(const Definition &def)
d = DefinitionData::get(def)->repo->definitionForName(m_defName);
auto data = DefinitionData::get(d);
data->load();
- if (m_contextName.isEmpty())
+ if (m_contextName.isEmpty()) {
m_context = data->initialContext();
+ }
}
if (!m_contextName.isEmpty()) {
m_context = DefinitionData::get(d)->contextByName(m_contextName);
- if (!m_context)
+ if (!m_context) {
qCWarning(Log) << "cannot find context" << m_contextName << "in" << def.name();
+ }
}
}
diff --git a/src/libs/3rdparty/syntax-highlighting/src/lib/definition.cpp b/src/libs/3rdparty/syntax-highlighting/src/lib/definition.cpp
index 7434e745b2..068907a4e2 100644
--- a/src/libs/3rdparty/syntax-highlighting/src/lib/definition.cpp
+++ b/src/libs/3rdparty/syntax-highlighting/src/lib/definition.cpp
@@ -52,29 +52,20 @@ DefinitionData *DefinitionData::get(const Definition &def)
Definition::Definition()
: d(new DefinitionData)
{
-}
-
-Definition::Definition(const Definition &other)
- : d(other.d)
-{
d->q = *this;
}
+Definition::Definition(Definition &&other) noexcept = default;
+Definition::Definition(const Definition &) = default;
+Definition::~Definition() = default;
+Definition &Definition::operator=(Definition &&other) noexcept = default;
+Definition &Definition::operator=(const Definition &) = default;
+
Definition::Definition(std::shared_ptr<DefinitionData> &&dd)
: d(std::move(dd))
{
}
-Definition::~Definition()
-{
-}
-
-Definition &Definition::operator=(const Definition &rhs)
-{
- d = rhs.d;
- return *this;
-}
-
bool Definition::operator==(const Definition &other) const
{
return d->fileName == other.d->fileName;
@@ -223,8 +214,9 @@ bool Definition::setKeywordList(const QString &name, const QStringList &content)
if (list) {
list->setKeywordList(content);
return true;
- } else
+ } else {
return false;
+ }
}
QVector<Format> Definition::formats() const
@@ -251,7 +243,7 @@ QVector<Definition> Definition::includedDefinitions() const
// Iterate all context rules to find associated Definitions. This will
// automatically catch other Definitions referenced with IncludeRuldes or ContextSwitch.
const auto definition = queue.takeLast();
- for (const auto &context : qAsConst(definition.d->contexts)) {
+ for (const auto &context : std::as_const(definition.d->contexts)) {
// handle context switch attributes of this context itself
for (const auto switchContext :
{context->lineEndContext().context(), context->lineEmptyContext().context(), context->fallthroughContext().context()}) {
@@ -321,8 +313,9 @@ Context *DefinitionData::initialContext() const
Context *DefinitionData::contextByName(const QString &wantedName) const
{
for (const auto context : contexts) {
- if (context->name() == wantedName)
+ if (context->name() == wantedName) {
return context;
+ }
}
return nullptr;
}
@@ -336,8 +329,9 @@ KeywordList *DefinitionData::keywordList(const QString &wantedName)
Format DefinitionData::formatByName(const QString &wantedName) const
{
const auto it = formats.constFind(wantedName);
- if (it != formats.constEnd())
+ if (it != formats.constEnd()) {
return it.value();
+ }
return Format();
}
@@ -349,24 +343,29 @@ bool DefinitionData::isLoaded() const
bool DefinitionData::load(OnlyKeywords onlyKeywords)
{
- if (fileName.isEmpty())
+ if (fileName.isEmpty()) {
return false;
+ }
- if (isLoaded())
+ if (isLoaded()) {
return true;
+ }
- if (bool(onlyKeywords) && keywordIsLoaded)
+ if (bool(onlyKeywords) && keywordIsLoaded) {
return true;
+ }
QFile file(fileName);
- if (!file.open(QFile::ReadOnly))
+ if (!file.open(QFile::ReadOnly)) {
return false;
+ }
QXmlStreamReader reader(&file);
while (!reader.atEnd()) {
const auto token = reader.readNext();
- if (token != QXmlStreamReader::StartElement)
+ if (token != QXmlStreamReader::StartElement) {
continue;
+ }
if (reader.name() == QLatin1String("highlighting")) {
loadHighlighting(reader, onlyKeywords);
@@ -375,21 +374,22 @@ bool DefinitionData::load(OnlyKeywords onlyKeywords)
}
}
- else if (reader.name() == QLatin1String("general"))
+ else if (reader.name() == QLatin1String("general")) {
loadGeneral(reader);
+ }
}
for (auto it = keywordLists.begin(); it != keywordLists.end(); ++it) {
it->setCaseSensitivity(caseSensitive);
}
- for (const auto context : qAsConst(contexts)) {
+ for (const auto context : std::as_const(contexts)) {
context->resolveContexts();
context->resolveIncludes();
context->resolveAttributeFormat();
}
- for (const auto context : qAsConst(contexts)) {
+ for (const auto context : std::as_const(contexts)) {
for (const auto &rule : context->rules()) {
rule->resolvePostProcessing();
}
@@ -427,14 +427,16 @@ bool DefinitionData::loadMetaData(const QString &definitionFileName)
fileName = definitionFileName;
QFile file(definitionFileName);
- if (!file.open(QFile::ReadOnly))
+ if (!file.open(QFile::ReadOnly)) {
return false;
+ }
QXmlStreamReader reader(&file);
while (!reader.atEnd()) {
const auto token = reader.readNext();
- if (token != QXmlStreamReader::StartElement)
+ if (token != QXmlStreamReader::StartElement) {
continue;
+ }
if (reader.name() == QLatin1String("language")) {
return loadLanguage(reader);
}
@@ -457,11 +459,13 @@ bool DefinitionData::loadMetaData(const QString &file, const QCborMap &obj)
fileName = file;
const auto exts = obj.value(QLatin1String("extensions")).toString();
- for (const auto &ext : exts.split(QLatin1Char(';'), Qt::SkipEmptyParts))
+ for (const auto &ext : exts.split(QLatin1Char(';'), Qt::SkipEmptyParts)) {
extensions.push_back(ext);
+ }
const auto mts = obj.value(QLatin1String("mimetype")).toString();
- for (const auto &mt : mts.split(QLatin1Char(';'), Qt::SkipEmptyParts))
+ for (const auto &mt : mts.split(QLatin1Char(';'), Qt::SkipEmptyParts)) {
mimetypes.push_back(mt);
+ }
return true;
}
@@ -471,8 +475,9 @@ bool DefinitionData::loadLanguage(QXmlStreamReader &reader)
Q_ASSERT(reader.name() == QLatin1String("language"));
Q_ASSERT(reader.tokenType() == QXmlStreamReader::StartElement);
- if (!checkKateVersion(reader.attributes().value(QLatin1String("kateversion"))))
+ if (!checkKateVersion(reader.attributes().value(QLatin1String("kateversion")))) {
return false;
+ }
name = reader.attributes().value(QLatin1String("name")).toString();
section = reader.attributes().value(QLatin1String("section")).toString();
@@ -485,13 +490,16 @@ bool DefinitionData::loadLanguage(QXmlStreamReader &reader)
author = reader.attributes().value(QLatin1String("author")).toString();
license = reader.attributes().value(QLatin1String("license")).toString();
const auto exts = reader.attributes().value(QLatin1String("extensions")).toString();
- for (const auto &ext : exts.split(QLatin1Char(';'), Qt::SkipEmptyParts))
+ for (const auto &ext : exts.split(QLatin1Char(';'), Qt::SkipEmptyParts)) {
extensions.push_back(ext);
+ }
const auto mts = reader.attributes().value(QLatin1String("mimetype")).toString();
- for (const auto &mt : mts.split(QLatin1Char(';'), Qt::SkipEmptyParts))
+ for (const auto &mt : mts.split(QLatin1Char(';'), Qt::SkipEmptyParts)) {
mimetypes.push_back(mt);
- if (reader.attributes().hasAttribute(QLatin1String("casesensitive")))
+ }
+ if (reader.attributes().hasAttribute(QLatin1String("casesensitive"))) {
caseSensitive = Xml::attrToBool(reader.attributes().value(QLatin1String("casesensitive"))) ? Qt::CaseSensitive : Qt::CaseInsensitive;
+ }
return true;
}
@@ -618,8 +626,9 @@ void DefinitionData::loadGeneral(QXmlStreamReader &reader)
++elementRefCounter;
if (reader.name() == QLatin1String("keywords")) {
- if (reader.attributes().hasAttribute(QLatin1String("casesensitive")))
+ if (reader.attributes().hasAttribute(QLatin1String("casesensitive"))) {
caseSensitive = Xml::attrToBool(reader.attributes().value(QLatin1String("casesensitive"))) ? Qt::CaseSensitive : Qt::CaseInsensitive;
+ }
// adapt wordDelimiters
wordDelimiters.append(reader.attributes().value(QLatin1String("additionalDeliminator")));
@@ -628,14 +637,15 @@ void DefinitionData::loadGeneral(QXmlStreamReader &reader)
// adapt WordWrapDelimiters
auto wordWrapDeliminatorAttr = reader.attributes().value(
QLatin1String("wordWrapDeliminator"));
- if (wordWrapDeliminatorAttr.isEmpty())
+ if (wordWrapDeliminatorAttr.isEmpty()) {
wordWrapDelimiters = wordDelimiters;
- else {
+ } else {
wordWrapDelimiters.append(wordWrapDeliminatorAttr);
}
} else if (reader.name() == QLatin1String("folding")) {
- if (reader.attributes().hasAttribute(QLatin1String("indentationsensitive")))
+ if (reader.attributes().hasAttribute(QLatin1String("indentationsensitive"))) {
indentationBasedFolding = Xml::attrToBool(reader.attributes().value(QLatin1String("indentationsensitive")));
+ }
} else if (reader.name() == QLatin1String("emptyLines")) {
loadFoldingIgnoreList(reader);
} else if (reader.name() == QLatin1String("comments")) {
@@ -649,8 +659,9 @@ void DefinitionData::loadGeneral(QXmlStreamReader &reader)
break;
case QXmlStreamReader::EndElement:
--elementRefCounter;
- if (elementRefCounter == 0)
+ if (elementRefCounter == 0) {
return;
+ }
reader.readNext();
break;
default:
@@ -688,8 +699,9 @@ void DefinitionData::loadComments(QXmlStreamReader &reader)
break;
case QXmlStreamReader::EndElement:
--elementRefCounter;
- if (elementRefCounter == 0)
+ if (elementRefCounter == 0) {
return;
+ }
reader.readNext();
break;
default:
@@ -719,8 +731,9 @@ void DefinitionData::loadFoldingIgnoreList(QXmlStreamReader &reader)
break;
case QXmlStreamReader::EndElement:
--elementRefCounter;
- if (elementRefCounter == 0)
+ if (elementRefCounter == 0) {
return;
+ }
reader.readNext();
break;
default:
@@ -754,8 +767,9 @@ void DefinitionData::loadSpellchecking(QXmlStreamReader &reader)
break;
case QXmlStreamReader::EndElement:
--elementRefCounter;
- if (elementRefCounter == 0)
+ if (elementRefCounter == 0) {
return;
+ }
reader.readNext();
break;
default:
@@ -798,10 +812,6 @@ DefinitionRef::DefinitionRef(const Definition &def)
{
}
-DefinitionRef::~DefinitionRef()
-{
-}
-
DefinitionRef &DefinitionRef::operator=(const Definition &def)
{
d = def.d;
@@ -810,8 +820,9 @@ DefinitionRef &DefinitionRef::operator=(const Definition &def)
Definition DefinitionRef::definition() const
{
- if (!d.expired())
+ if (!d.expired()) {
return Definition(d.lock());
+ }
return Definition();
}
diff --git a/src/libs/3rdparty/syntax-highlighting/src/lib/definition.h b/src/libs/3rdparty/syntax-highlighting/src/lib/definition.h
index 8226fbdd24..05757ea52a 100644
--- a/src/libs/3rdparty/syntax-highlighting/src/lib/definition.h
+++ b/src/libs/3rdparty/syntax-highlighting/src/lib/definition.h
@@ -13,6 +13,7 @@
#include <QPair>
#include <QVector>
#include <memory>
+#include <qobjectdefs.h>
QT_BEGIN_NAMESPACE
class QChar;
@@ -74,7 +75,7 @@ enum class CommentPosition {
* singleLineCommentMarker() and multiLineCommentMarker() provide comment
* markers that can be used for commenting/uncommenting code. Similarly,
* formats() returns a list of Format items defined by this Definition (which
- * equal the itemDatas of a highlighing definition file). includedDefinitions()
+ * equal the itemDatas of a highlighting definition file). includedDefinitions()
* returns a list of all included Definition%s referenced by this Definition via
* the rule IncludeRules, which is useful for displaying all Format items for
* color configuration in the user interface.
@@ -84,6 +85,13 @@ enum class CommentPosition {
*/
class KSYNTAXHIGHLIGHTING_EXPORT Definition
{
+ Q_GADGET
+ Q_PROPERTY(QString name READ name)
+ Q_PROPERTY(QString translatedName READ translatedName)
+ Q_PROPERTY(QString section READ section)
+ Q_PROPERTY(QString translatedSection READ translatedSection)
+ Q_PROPERTY(QString author READ author)
+ Q_PROPERTY(QString license READ license)
public:
/**
* Default constructor, creating an empty (invalid) Definition instance.
@@ -94,6 +102,14 @@ public:
Definition();
/**
+ * Move constructor.
+ * This definition takes the Definition data from @p other.
+ * @note @p other may only be assigned to or destroyed afterwards.
+ * @since 5.86
+ */
+ Definition(Definition &&other) noexcept;
+
+ /**
* Copy constructor.
* Both this definition as well as @p other share the Definition data.
*/
@@ -105,7 +121,15 @@ public:
~Definition();
/**
- * Assignment operator.
+ * Move assignment operator.
+ * This definition takes the Definition data from @p other.
+ * @note @p other may only be assigned to or destroyed afterwards.
+ * @since 5.86
+ */
+ Definition &operator=(Definition &&other) noexcept;
+
+ /**
+ * Copy assignment operator.
* Both this definition as well as @p rhs share the Definition data.
*/
Definition &operator=(const Definition &rhs);
diff --git a/src/libs/3rdparty/syntax-highlighting/src/lib/definitiondownloader.cpp b/src/libs/3rdparty/syntax-highlighting/src/lib/definitiondownloader.cpp
index 3dff1dd436..b16139b731 100644
--- a/src/libs/3rdparty/syntax-highlighting/src/lib/definitiondownloader.cpp
+++ b/src/libs/3rdparty/syntax-highlighting/src/lib/definitiondownloader.cpp
@@ -51,24 +51,27 @@ void DefinitionDownloaderPrivate::definitionListDownloadFinished(QNetworkReply *
while (!parser.atEnd()) {
switch (parser.readNext()) {
case QXmlStreamReader::StartElement:
- if (parser.name() == QLatin1String("Definition"))
+ if (parser.name() == QLatin1String("Definition")) {
updateDefinition(parser);
+ }
break;
default:
break;
}
}
- if (pendingDownloads == 0)
+ if (pendingDownloads == 0) {
Q_EMIT q->informationMessage(QObject::tr("All syntax definitions are up-to-date."));
+ }
checkDone();
}
void DefinitionDownloaderPrivate::updateDefinition(QXmlStreamReader &parser)
{
const auto name = parser.attributes().value(QLatin1String("name"));
- if (name.isEmpty())
+ if (name.isEmpty()) {
return;
+ }
auto localDef = repo->definitionForName(name.toString());
if (!localDef.isValid()) {
@@ -86,11 +89,13 @@ void DefinitionDownloaderPrivate::updateDefinition(QXmlStreamReader &parser)
void DefinitionDownloaderPrivate::downloadDefinition(const QUrl &downloadUrl)
{
- if (!downloadUrl.isValid())
+ if (!downloadUrl.isValid()) {
return;
+ }
auto url = downloadUrl;
- if (url.scheme() == QLatin1String("http"))
+ if (url.scheme() == QLatin1String("http")) {
url.setScheme(QStringLiteral("https"));
+ }
QNetworkRequest req(url);
auto reply = nam->get(req);
@@ -133,8 +138,9 @@ void DefinitionDownloaderPrivate::downloadDefinitionFinished(QNetworkReply *repl
void DefinitionDownloaderPrivate::checkDone()
{
if (pendingDownloads == 0) {
- if (needsReload)
+ if (needsReload) {
repo->reload();
+ }
Q_EMIT QTimer::singleShot(0, q, &DefinitionDownloader::done);
}
diff --git a/src/libs/3rdparty/syntax-highlighting/src/lib/definitionref_p.h b/src/libs/3rdparty/syntax-highlighting/src/lib/definitionref_p.h
index 25a1a749e4..285fec3e20 100644
--- a/src/libs/3rdparty/syntax-highlighting/src/lib/definitionref_p.h
+++ b/src/libs/3rdparty/syntax-highlighting/src/lib/definitionref_p.h
@@ -13,7 +13,6 @@ namespace KSyntaxHighlighting
{
class Definition;
class DefinitionData;
-class DefinitionPrivate;
/** Weak reference for Definition instances.
*
@@ -21,6 +20,8 @@ class DefinitionPrivate;
* in objects hold directly or indirectly by Definition
* to avoid reference count loops and thus memory leaks.
*
+ * This class follows the rule of zero. It is implicitly movable and copyable.
+ *
* @internal
*/
class DefinitionRef
@@ -28,7 +29,6 @@ class DefinitionRef
public:
DefinitionRef();
explicit DefinitionRef(const Definition &def);
- ~DefinitionRef();
DefinitionRef &operator=(const Definition &def);
Definition definition() const;
diff --git a/src/libs/3rdparty/syntax-highlighting/src/lib/format.cpp b/src/libs/3rdparty/syntax-highlighting/src/lib/format.cpp
index d459ee36d8..bcc64c3c2b 100644
--- a/src/libs/3rdparty/syntax-highlighting/src/lib/format.cpp
+++ b/src/libs/3rdparty/syntax-highlighting/src/lib/format.cpp
@@ -21,8 +21,9 @@ using namespace KSyntaxHighlighting;
static Theme::TextStyle stringToDefaultFormat(QStringView str)
{
- if (!str.startsWith(QLatin1String("ds")))
+ if (!str.startsWith(QLatin1String("ds"))) {
return Theme::Normal;
+ }
static const auto idx = Theme::staticMetaObject.indexOfEnumerator("TextStyle");
Q_ASSERT(idx >= 0);
@@ -30,8 +31,9 @@ static Theme::TextStyle stringToDefaultFormat(QStringView str)
bool ok = false;
const auto value = metaEnum.keyToValue(str.mid(2).toLatin1().constData(), &ok);
- if (!ok || value < 0)
+ if (!ok || value < 0) {
return Theme::Normal;
+ }
return static_cast<Theme::TextStyle>(value);
}
@@ -44,8 +46,9 @@ FormatPrivate *FormatPrivate::detachAndGet(Format &format)
TextStyleData FormatPrivate::styleOverride(const Theme &theme) const
{
const auto themeData = ThemeData::get(theme);
- if (themeData)
+ if (themeData) {
return themeData->textStyleOverride(definition.definition().name(), name);
+ }
return TextStyleData();
}
@@ -113,16 +116,18 @@ bool Format::hasTextColor(const Theme &theme) const
QColor Format::textColor(const Theme &theme) const
{
const auto overrideStyle = d->styleOverride(theme);
- if (overrideStyle.textColor)
+ if (overrideStyle.textColor) {
return overrideStyle.textColor;
+ }
return d->style.textColor ? QColor::fromRgba(d->style.textColor) : QColor::fromRgba(theme.textColor(d->defaultStyle));
}
QColor Format::selectedTextColor(const Theme &theme) const
{
const auto overrideStyle = d->styleOverride(theme);
- if (overrideStyle.selectedTextColor)
+ if (overrideStyle.selectedTextColor) {
return overrideStyle.selectedTextColor;
+ }
return d->style.selectedTextColor ? QColor::fromRgba(d->style.selectedTextColor) : QColor::fromRgba(theme.selectedTextColor(d->defaultStyle));
}
@@ -136,8 +141,9 @@ bool Format::hasBackgroundColor(const Theme &theme) const
QColor Format::backgroundColor(const Theme &theme) const
{
const auto overrideStyle = d->styleOverride(theme);
- if (overrideStyle.backgroundColor)
+ if (overrideStyle.backgroundColor) {
return overrideStyle.backgroundColor;
+ }
// use QColor::fromRgba for background QRgb => QColor conversion to avoid unset colors == black!
return d->style.backgroundColor ? QColor::fromRgba(d->style.backgroundColor) : QColor::fromRgba(theme.backgroundColor(d->defaultStyle));
@@ -146,8 +152,9 @@ QColor Format::backgroundColor(const Theme &theme) const
QColor Format::selectedBackgroundColor(const Theme &theme) const
{
const auto overrideStyle = d->styleOverride(theme);
- if (overrideStyle.selectedBackgroundColor)
+ if (overrideStyle.selectedBackgroundColor) {
return overrideStyle.selectedBackgroundColor;
+ }
// use QColor::fromRgba for background QRgb => QColor conversion to avoid unset colors == black!
return d->style.selectedBackgroundColor ? QColor::fromRgba(d->style.selectedBackgroundColor)
@@ -157,32 +164,36 @@ QColor Format::selectedBackgroundColor(const Theme &theme) const
bool Format::isBold(const Theme &theme) const
{
const auto overrideStyle = d->styleOverride(theme);
- if (overrideStyle.hasBold)
+ if (overrideStyle.hasBold) {
return overrideStyle.bold;
+ }
return d->style.hasBold ? d->style.bold : theme.isBold(d->defaultStyle);
}
bool Format::isItalic(const Theme &theme) const
{
const auto overrideStyle = d->styleOverride(theme);
- if (overrideStyle.hasItalic)
+ if (overrideStyle.hasItalic) {
return overrideStyle.italic;
+ }
return d->style.hasItalic ? d->style.italic : theme.isItalic(d->defaultStyle);
}
bool Format::isUnderline(const Theme &theme) const
{
const auto overrideStyle = d->styleOverride(theme);
- if (overrideStyle.hasUnderline)
+ if (overrideStyle.hasUnderline) {
return overrideStyle.underline;
+ }
return d->style.hasUnderline ? d->style.underline : theme.isUnderline(d->defaultStyle);
}
bool Format::isStrikeThrough(const Theme &theme) const
{
const auto overrideStyle = d->styleOverride(theme);
- if (overrideStyle.hasStrikeThrough)
+ if (overrideStyle.hasStrikeThrough) {
return overrideStyle.strikeThrough;
+ }
return d->style.hasStrikeThrough ? d->style.strikeThrough : theme.isStrikeThrough(d->defaultStyle);
}
diff --git a/src/libs/3rdparty/syntax-highlighting/src/lib/htmlhighlighter.cpp b/src/libs/3rdparty/syntax-highlighting/src/lib/htmlhighlighter.cpp
index 5ba421d0e1..688a42d45c 100644
--- a/src/libs/3rdparty/syntax-highlighting/src/lib/htmlhighlighter.cpp
+++ b/src/libs/3rdparty/syntax-highlighting/src/lib/htmlhighlighter.cpp
@@ -70,10 +70,11 @@ void HtmlHighlighter::highlightFile(const QString &fileName, const QString &titl
return;
}
- if (title.isEmpty())
+ if (title.isEmpty()) {
highlightData(&f, fi.fileName());
- else
+ } else {
highlightData(&f, title);
+ }
}
/**
@@ -87,8 +88,9 @@ void HtmlHighlighter::highlightFile(const QString &fileName, const QString &titl
*/
static QString toHtmlRgbaString(const QColor &color)
{
- if (color.alpha() == 0xFF)
+ if (color.alpha() == 0xFF) {
return color.name();
+ }
QString rgba = QStringLiteral("rgba(");
rgba.append(QString::number(color.red()));
@@ -111,10 +113,11 @@ void HtmlHighlighter::highlightData(QIODevice *dev, const QString &title)
}
QString htmlTitle;
- if (title.isEmpty())
+ if (title.isEmpty()) {
htmlTitle = QStringLiteral("Kate Syntax Highlighter");
- else
+ } else {
htmlTitle = title.toHtmlEscaped();
+ }
State state;
*d->out << "<!DOCTYPE html>\n";
@@ -125,8 +128,9 @@ void HtmlHighlighter::highlightData(QIODevice *dev, const QString &title)
<< ")\"/>\n";
*d->out << "</head><body";
*d->out << " style=\"background-color:" << toHtmlRgbaString(QColor::fromRgba(theme().editorColor(Theme::BackgroundColor)));
- if (theme().textColor(Theme::Normal))
+ if (theme().textColor(Theme::Normal)) {
*d->out << ";color:" << toHtmlRgbaString(QColor::fromRgba(theme().textColor(Theme::Normal)));
+ }
*d->out << "\"><pre>\n";
QTextStream in(dev);
@@ -148,27 +152,34 @@ void HtmlHighlighter::highlightData(QIODevice *dev, const QString &title)
void HtmlHighlighter::applyFormat(int offset, int length, const Format &format)
{
- if (length == 0)
+ if (length == 0) {
return;
+ }
// collect potential output, cheaper than thinking about "is there any?"
QVarLengthArray<QString, 16> formatOutput;
- if (format.hasTextColor(theme()))
+ if (format.hasTextColor(theme())) {
formatOutput << QStringLiteral("color:") << toHtmlRgbaString(format.textColor(theme())) << QStringLiteral(";");
- if (format.hasBackgroundColor(theme()))
+ }
+ if (format.hasBackgroundColor(theme())) {
formatOutput << QStringLiteral("background-color:") << toHtmlRgbaString(format.backgroundColor(theme())) << QStringLiteral(";");
- if (format.isBold(theme()))
+ }
+ if (format.isBold(theme())) {
formatOutput << QStringLiteral("font-weight:bold;");
- if (format.isItalic(theme()))
+ }
+ if (format.isItalic(theme())) {
formatOutput << QStringLiteral("font-style:italic;");
- if (format.isUnderline(theme()))
+ }
+ if (format.isUnderline(theme())) {
formatOutput << QStringLiteral("text-decoration:underline;");
- if (format.isStrikeThrough(theme()))
+ }
+ if (format.isStrikeThrough(theme())) {
formatOutput << QStringLiteral("text-decoration:line-through;");
+ }
if (!formatOutput.isEmpty()) {
*d->out << "<span style=\"";
- for (const auto &out : qAsConst(formatOutput)) {
+ for (const auto &out : std::as_const(formatOutput)) {
*d->out << out;
}
*d->out << "\">";
diff --git a/src/libs/3rdparty/syntax-highlighting/src/lib/keywordlist.cpp b/src/libs/3rdparty/syntax-highlighting/src/lib/keywordlist.cpp
index b13e30607b..3a7514897a 100644
--- a/src/libs/3rdparty/syntax-highlighting/src/lib/keywordlist.cpp
+++ b/src/libs/3rdparty/syntax-highlighting/src/lib/keywordlist.cpp
@@ -16,6 +16,27 @@
using namespace KSyntaxHighlighting;
+namespace
+{
+struct KeywordComparator {
+ Qt::CaseSensitivity caseSensitive;
+
+ bool operator()(QStringView a, QStringView b) const
+ {
+ if (a.size() < b.size()) {
+ return true;
+ }
+
+ if (a.size() > b.size()) {
+ return false;
+ }
+
+ return a.compare(b, caseSensitive) < 0;
+ }
+};
+
+}
+
bool KeywordList::contains(QStringView str, Qt::CaseSensitivity caseSensitive) const
{
/**
@@ -26,9 +47,7 @@ bool KeywordList::contains(QStringView str, Qt::CaseSensitivity caseSensitive) c
/**
* search with right predicate
*/
- return std::binary_search(vectorToSearch.begin(), vectorToSearch.end(), QStringView(str), [caseSensitive](QStringView a, QStringView b) {
- return a.compare(b, caseSensitive) < 0;
- });
+ return std::binary_search(vectorToSearch.begin(), vectorToSearch.end(), QStringView(str), KeywordComparator{caseSensitive});
}
void KeywordList::load(QXmlStreamReader &reader)
@@ -85,16 +104,14 @@ void KeywordList::initLookupForCaseSensitivity(Qt::CaseSensitivity caseSensitive
* fill vector with refs to keywords
*/
vectorToSort.reserve(m_keywords.size());
- for (const auto &keyword : qAsConst(m_keywords)) {
+ for (const auto &keyword : std::as_const(m_keywords)) {
vectorToSort.push_back(keyword);
}
/**
* sort with right predicate
*/
- std::sort(vectorToSort.begin(), vectorToSort.end(), [caseSensitive](QStringView a, QStringView b) {
- return a.compare(b, caseSensitive) < 0;
- });
+ std::sort(vectorToSort.begin(), vectorToSort.end(), KeywordComparator{caseSensitive});
}
void KeywordList::resolveIncludeKeywords(DefinitionData &def)
diff --git a/src/libs/3rdparty/syntax-highlighting/src/lib/repository.cpp b/src/libs/3rdparty/syntax-highlighting/src/lib/repository.cpp
index 1e3191a7bc..f3b36df459 100644
--- a/src/libs/3rdparty/syntax-highlighting/src/lib/repository.cpp
+++ b/src/libs/3rdparty/syntax-highlighting/src/lib/repository.cpp
@@ -11,7 +11,7 @@
#include "repository_p.h"
#include "theme.h"
#include "themedata_p.h"
-#include "wildcardmatcher_p.h"
+#include "wildcardmatcher.h"
#include <QCborMap>
#include <QCborValue>
@@ -19,15 +19,75 @@
#include <QFile>
#include <QFileInfo>
#include <QPalette>
+#include <QString>
+#include <QStringView>
#ifndef NO_STANDARD_PATHS
#include <QStandardPaths>
#endif
+#include <algorithm>
+#include <iterator>
#include <limits>
using namespace KSyntaxHighlighting;
+namespace
+{
+QString fileNameFromFilePath(const QString &filePath)
+{
+ return QFileInfo{filePath}.fileName();
+}
+
+auto anyWildcardMatches(QStringView str)
+{
+ return [str](const Definition &def) {
+ const auto strings = def.extensions();
+ return std::any_of(strings.cbegin(), strings.cend(), [str](QStringView wildcard) {
+ return WildcardMatcher::exactMatch(str, wildcard);
+ });
+ };
+}
+
+auto anyMimeTypeEquals(QStringView mimeTypeName)
+{
+ return [mimeTypeName](const Definition &def) {
+ const auto strings = def.mimeTypes();
+ return std::any_of(strings.cbegin(), strings.cend(), [mimeTypeName](QStringView name) {
+ return mimeTypeName == name;
+ });
+ };
+}
+
+// The two function templates below take defs - a map sorted by highlighting name - to be deterministic and independent of translations.
+
+template<typename UnaryPredicate>
+Definition findHighestPriorityDefinitionIf(const QMap<QString, Definition> &defs, UnaryPredicate predicate)
+{
+ const Definition *match = nullptr;
+ auto matchPriority = std::numeric_limits<int>::lowest();
+ for (const Definition &def : defs) {
+ const auto defPriority = def.priority();
+ if (defPriority > matchPriority && predicate(def)) {
+ match = &def;
+ matchPriority = defPriority;
+ }
+ }
+ return match == nullptr ? Definition{} : *match;
+}
+
+template<typename UnaryPredicate>
+QVector<Definition> findDefinitionsIf(const QMap<QString, Definition> &defs, UnaryPredicate predicate)
+{
+ QVector<Definition> matches;
+ std::copy_if(defs.cbegin(), defs.cend(), std::back_inserter(matches), predicate);
+ std::stable_sort(matches.begin(), matches.end(), [](const Definition &lhs, const Definition &rhs) {
+ return lhs.priority() > rhs.priority();
+ });
+ return matches;
+}
+} // unnamed namespace
+
static void initResource()
{
#ifdef HAS_SYNTAX_RESOURCE
@@ -52,8 +112,9 @@ Repository::~Repository()
{
// reset repo so we can detect in still alive definition instances
// that the repo was deleted
- for (const auto &def : qAsConst(d->m_sortedDefs))
+ for (const auto &def : std::as_const(d->m_sortedDefs)) {
DefinitionData::get(def)->repo = nullptr;
+ }
}
Definition Repository::definitionForName(const QString &defName) const
@@ -61,58 +122,24 @@ Definition Repository::definitionForName(const QString &defName) const
return d->m_defs.value(defName);
}
-static void sortDefinitions(QVector<Definition> &definitions)
-{
- std::stable_sort(definitions.begin(), definitions.end(), [](const Definition &lhs, const Definition &rhs) {
- return lhs.priority() > rhs.priority();
- });
-}
-
Definition Repository::definitionForFileName(const QString &fileName) const
{
- return definitionsForFileName(fileName).value(0);
+ return findHighestPriorityDefinitionIf(d->m_defs, anyWildcardMatches(fileNameFromFilePath(fileName)));
}
QVector<Definition> Repository::definitionsForFileName(const QString &fileName) const
{
- QFileInfo fi(fileName);
- const auto name = fi.fileName();
-
- // use d->m_defs, sorted map by highlighting name, to be deterministic and independent of translations
- QVector<Definition> candidates;
- for (const Definition &def : qAsConst(d->m_defs)) {
- for (const auto &pattern : def.extensions()) {
- if (WildcardMatcher::exactMatch(name, pattern)) {
- candidates.push_back(def);
- break;
- }
- }
- }
-
- sortDefinitions(candidates);
- return candidates;
+ return findDefinitionsIf(d->m_defs, anyWildcardMatches(fileNameFromFilePath(fileName)));
}
Definition Repository::definitionForMimeType(const QString &mimeType) const
{
- return definitionsForMimeType(mimeType).value(0);
+ return findHighestPriorityDefinitionIf(d->m_defs, anyMimeTypeEquals(mimeType));
}
QVector<Definition> Repository::definitionsForMimeType(const QString &mimeType) const
{
- // use d->m_defs, sorted map by highlighting name, to be deterministic and independent of translations
- QVector<Definition> candidates;
- for (const Definition &def : qAsConst(d->m_defs)) {
- for (const auto &matchType : def.mimeTypes()) {
- if (mimeType == matchType) {
- candidates.push_back(def);
- break;
- }
- }
- }
-
- sortDefinitions(candidates);
- return candidates;
+ return findDefinitionsIf(d->m_defs, anyMimeTypeEquals(mimeType));
}
QVector<Definition> Repository::definitions() const
@@ -127,7 +154,7 @@ QVector<Theme> Repository::themes() const
Theme Repository::theme(const QString &themeName) const
{
- for (const auto &theme : qAsConst(d->m_themes)) {
+ for (const auto &theme : std::as_const(d->m_themes)) {
if (theme.name() == themeName) {
return theme;
}
@@ -138,14 +165,15 @@ Theme Repository::theme(const QString &themeName) const
Theme Repository::defaultTheme(Repository::DefaultTheme t) const
{
- if (t == DarkTheme)
+ if (t == DarkTheme) {
return theme(QLatin1String("Breeze Dark"));
+ }
return theme(QLatin1String("Breeze Light"));
}
Theme Repository::defaultTheme(Repository::DefaultTheme t)
{
- return qAsConst(*this).defaultTheme(t);
+ return std::as_const(*this).defaultTheme(t);
}
Theme Repository::themeForPalette(const QPalette &palette) const
@@ -164,7 +192,7 @@ Theme Repository::themeForPalette(const QPalette &palette) const
if (!matchingThemes.empty()) {
// if there's multiple, search for one with a matching highlight color
const auto highlight = palette.color(QPalette::Highlight);
- for (const auto &theme : qAsConst(matchingThemes)) {
+ for (const auto &theme : std::as_const(matchingThemes)) {
auto selection = theme.editorColor(KSyntaxHighlighting::Theme::EditorColorRole::TextSelection);
if (selection == highlight.rgb()) {
return theme;
@@ -179,7 +207,7 @@ Theme Repository::themeForPalette(const QPalette &palette) const
Theme Repository::themeForPalette(const QPalette &palette)
{
- return qAsConst(*this).themeForPalette(palette);
+ return std::as_const(*this).themeForPalette(palette);
}
void RepositoryPrivate::load(Repository *repo)
@@ -189,29 +217,39 @@ void RepositoryPrivate::load(Repository *repo)
// do lookup in standard paths, if not disabled
#ifndef NO_STANDARD_PATHS
- for (const auto &dir :
- QStandardPaths::locateAll(QStandardPaths::GenericDataLocation, QStringLiteral("org.kde.syntax-highlighting/syntax"), QStandardPaths::LocateDirectory))
+ for (const auto &dir : QStandardPaths::locateAll(QStandardPaths::GenericDataLocation,
+ QStringLiteral("org.kde.syntax-highlighting/syntax"),
+ QStandardPaths::LocateDirectory)) {
loadSyntaxFolder(repo, dir);
+ }
// backward compatibility with Kate
- for (const auto &dir : QStandardPaths::locateAll(QStandardPaths::GenericDataLocation, QStringLiteral("katepart5/syntax"), QStandardPaths::LocateDirectory))
+ for (const auto &dir :
+ QStandardPaths::locateAll(QStandardPaths::GenericDataLocation, QStringLiteral("katepart5/syntax"), QStandardPaths::LocateDirectory)) {
loadSyntaxFolder(repo, dir);
+ }
#endif
- // default resources are always used
- loadSyntaxFolder(repo, QStringLiteral(":/org.kde.syntax-highlighting/syntax"));
+ // default resources are always used, this is the one location that has a index cbor file
+ loadSyntaxFolderFromIndex(repo, QStringLiteral(":/org.kde.syntax-highlighting/syntax"));
+
+ // extra resources provided by 3rdparty libraries/applications
+ loadSyntaxFolder(repo, QStringLiteral(":/org.kde.syntax-highlighting/syntax-addons"));
// user given extra paths
- for (const auto &path : qAsConst(m_customSearchPaths))
+ for (const auto &path : std::as_const(m_customSearchPaths)) {
loadSyntaxFolder(repo, path + QStringLiteral("/syntax"));
+ }
m_sortedDefs.reserve(m_defs.size());
- for (auto it = m_defs.constBegin(); it != m_defs.constEnd(); ++it)
+ for (auto it = m_defs.constBegin(); it != m_defs.constEnd(); ++it) {
m_sortedDefs.push_back(it.value());
+ }
std::sort(m_sortedDefs.begin(), m_sortedDefs.end(), [](const Definition &left, const Definition &right) {
auto comparison = left.translatedSection().compare(right.translatedSection(), Qt::CaseInsensitive);
- if (comparison == 0)
+ if (comparison == 0) {
comparison = left.translatedName().compare(right.translatedName(), Qt::CaseInsensitive);
+ }
return comparison < 0;
});
@@ -219,54 +257,60 @@ void RepositoryPrivate::load(Repository *repo)
// do lookup in standard paths, if not disabled
#ifndef NO_STANDARD_PATHS
- for (const auto &dir :
- QStandardPaths::locateAll(QStandardPaths::GenericDataLocation, QStringLiteral("org.kde.syntax-highlighting/themes"), QStandardPaths::LocateDirectory))
+ for (const auto &dir : QStandardPaths::locateAll(QStandardPaths::GenericDataLocation,
+ QStringLiteral("org.kde.syntax-highlighting/themes"),
+ QStandardPaths::LocateDirectory)) {
loadThemeFolder(dir);
+ }
#endif
// default resources are always used
loadThemeFolder(QStringLiteral(":/org.kde.syntax-highlighting/themes"));
+ // extra resources provided by 3rdparty libraries/applications
+ loadThemeFolder(QStringLiteral(":/org.kde.syntax-highlighting/themes-addons"));
+
// user given extra paths
- for (const auto &path : qAsConst(m_customSearchPaths))
+ for (const auto &path : std::as_const(m_customSearchPaths)) {
loadThemeFolder(path + QStringLiteral("/themes"));
+ }
}
void RepositoryPrivate::loadSyntaxFolder(Repository *repo, const QString &path)
{
- if (loadSyntaxFolderFromIndex(repo, path))
- return;
-
QDirIterator it(path, QStringList() << QLatin1String("*.xml"), QDir::Files);
while (it.hasNext()) {
Definition def;
auto defData = DefinitionData::get(def);
defData->repo = repo;
- if (defData->loadMetaData(it.next()))
+ if (defData->loadMetaData(it.next())) {
addDefinition(def);
+ }
}
}
-bool RepositoryPrivate::loadSyntaxFolderFromIndex(Repository *repo, const QString &path)
+void RepositoryPrivate::loadSyntaxFolderFromIndex(Repository *repo, const QString &path)
{
QFile indexFile(path + QLatin1String("/index.katesyntax"));
- if (!indexFile.open(QFile::ReadOnly))
- return false;
+ if (!indexFile.open(QFile::ReadOnly)) {
+ return;
+ }
const auto indexDoc(QCborValue::fromCbor(indexFile.readAll()));
const auto index = indexDoc.toMap();
for (auto it = index.begin(); it != index.end(); ++it) {
- if (!it.value().isMap())
+ if (!it.value().isMap()) {
continue;
+ }
const auto fileName = QString(path + QLatin1Char('/') + it.key().toString());
const auto defMap = it.value().toMap();
Definition def;
auto defData = DefinitionData::get(def);
defData->repo = repo;
- if (defData->loadMetaData(fileName, defMap))
+ if (defData->loadMetaData(fileName, defMap)) {
addDefinition(def);
+ }
}
- return true;
}
void RepositoryPrivate::addDefinition(const Definition &def)
@@ -277,8 +321,9 @@ void RepositoryPrivate::addDefinition(const Definition &def)
return;
}
- if (it.value().version() >= def.version())
+ if (it.value().version() >= def.version()) {
return;
+ }
m_defs.insert(def.name(), def);
}
@@ -287,8 +332,9 @@ void RepositoryPrivate::loadThemeFolder(const QString &path)
QDirIterator it(path, QStringList() << QLatin1String("*.theme"), QDir::Files);
while (it.hasNext()) {
auto themeData = std::unique_ptr<ThemeData>(new ThemeData);
- if (themeData->load(it.next()))
+ if (themeData->load(it.next())) {
addTheme(Theme(themeData.release()));
+ }
}
}
@@ -307,15 +353,17 @@ void RepositoryPrivate::addTheme(const Theme &theme)
m_themes.insert(it, theme);
return;
}
- if (themeRevision(*it) < themeRevision(theme))
+ if (themeRevision(*it) < themeRevision(theme)) {
*it = theme;
+ }
}
quint16 RepositoryPrivate::foldingRegionId(const QString &defName, const QString &foldName)
{
const auto it = m_foldingRegionIds.constFind(qMakePair(defName, foldName));
- if (it != m_foldingRegionIds.constEnd())
+ if (it != m_foldingRegionIds.constEnd()) {
return it.value();
+ }
m_foldingRegionIds.insert(qMakePair(defName, foldName), ++m_foldingRegionId);
return m_foldingRegionId;
}
@@ -329,8 +377,9 @@ quint16 RepositoryPrivate::nextFormatId()
void Repository::reload()
{
qCDebug(Log) << "Reloading syntax definitions!";
- for (const auto &def : qAsConst(d->m_sortedDefs))
+ for (const auto &def : std::as_const(d->m_sortedDefs)) {
DefinitionData::get(def)->clear();
+ }
d->m_defs.clear();
d->m_sortedDefs.clear();
diff --git a/src/libs/3rdparty/syntax-highlighting/src/lib/repository.h b/src/libs/3rdparty/syntax-highlighting/src/lib/repository.h
index 323407f008..9e19ecda56 100644
--- a/src/libs/3rdparty/syntax-highlighting/src/lib/repository.h
+++ b/src/libs/3rdparty/syntax-highlighting/src/lib/repository.h
@@ -86,6 +86,11 @@ class Theme;
* The internal resource path is ":/org.kde.syntax-highlighting/syntax".
* This path should never be touched by other applications.
*
+ * -# Then, all custom files compiled into resources are loaded.
+ * The resource path is ":/org.kde.syntax-highlighting/syntax-addons".
+ * This path can be used by other libraries/applications to bundle specialized definitions.
+ * Per default this path isn't used by the framework itself.
+ *
* -# Finally, the search path can be extended by calling addCustomSearchPath().
* A custom search path can either be a path on disk or again a path to
* a Qt resource.
@@ -102,6 +107,11 @@ class Theme;
* The internal resource path is ":/org.kde.syntax-highlighting/themes".
* This path should never be touched by other applications.
*
+ * -# Then, all custom files compiled into resources are loaded.
+ * The resource path is ":/org.kde.syntax-highlighting/themes-addons".
+ * This path can be used by other libraries/applications to bundle specialized themes.
+ * Per default this path isn't used by the framework itself.
+ *
* -# Finally, all Theme%s located in the paths added addCustomSearchPath()
* are loaded.
*
diff --git a/src/libs/3rdparty/syntax-highlighting/src/lib/repository_p.h b/src/libs/3rdparty/syntax-highlighting/src/lib/repository_p.h
index 447cfae699..abc992358d 100644
--- a/src/libs/3rdparty/syntax-highlighting/src/lib/repository_p.h
+++ b/src/libs/3rdparty/syntax-highlighting/src/lib/repository_p.h
@@ -29,7 +29,7 @@ public:
void load(Repository *repo);
void loadSyntaxFolder(Repository *repo, const QString &path);
- bool loadSyntaxFolderFromIndex(Repository *repo, const QString &path);
+ void loadSyntaxFolderFromIndex(Repository *repo, const QString &path);
void addDefinition(const Definition &def);
diff --git a/src/libs/3rdparty/syntax-highlighting/src/lib/rule.cpp b/src/libs/3rdparty/syntax-highlighting/src/lib/rule.cpp
index c8d3fa0e63..f4e88b719a 100644
--- a/src/libs/3rdparty/syntax-highlighting/src/lib/rule.cpp
+++ b/src/libs/3rdparty/syntax-highlighting/src/lib/rule.cpp
@@ -34,10 +34,11 @@ static bool isHexChar(QChar c)
return isDigit(c) || (c <= QLatin1Char('f') && QLatin1Char('a') <= c) || (c <= QLatin1Char('F') && QLatin1Char('A') <= c);
}
-static int matchEscapedChar(const QString &text, int offset)
+static int matchEscapedChar(QStringView text, int offset)
{
- if (text.at(offset) != QLatin1Char('\\') || text.size() < offset + 2)
+ if (text.at(offset) != QLatin1Char('\\') || text.size() < offset + 2) {
return offset;
+ }
const auto c = text.at(offset + 1);
switch (c.unicode()) {
@@ -59,8 +60,9 @@ static int matchEscapedChar(const QString &text, int offset)
// hex encoded character
case 'x':
if (offset + 2 < text.size() && isHexChar(text.at(offset + 2))) {
- if (offset + 3 < text.size() && isHexChar(text.at(offset + 3)))
+ if (offset + 3 < text.size() && isHexChar(text.at(offset + 3))) {
return offset + 4;
+ }
return offset + 3;
}
return offset;
@@ -75,8 +77,9 @@ static int matchEscapedChar(const QString &text, int offset)
case '6':
case '7':
if (offset + 2 < text.size() && isOctalChar(text.at(offset + 2))) {
- if (offset + 3 < text.size() && isOctalChar(text.at(offset + 3)))
+ if (offset + 3 < text.size() && isOctalChar(text.at(offset + 3))) {
return offset + 4;
+ }
return offset + 3;
}
return offset + 2;
@@ -116,26 +119,31 @@ bool Rule::load(QXmlStreamReader &reader)
Q_ASSERT(reader.tokenType() == QXmlStreamReader::StartElement);
m_attribute = reader.attributes().value(QLatin1String("attribute")).toString();
- if (reader.name() != QLatin1String("IncludeRules")) // IncludeRules uses this with a different semantic
+ if (reader.name() != QLatin1String("IncludeRules")) { // IncludeRules uses this with a different semantic
m_context.parse(reader.attributes().value(QLatin1String("context")));
+ }
m_firstNonSpace = Xml::attrToBool(reader.attributes().value(QLatin1String("firstNonSpace")));
m_lookAhead = Xml::attrToBool(reader.attributes().value(QLatin1String("lookAhead")));
bool colOk = false;
m_column = reader.attributes().value(QLatin1String("column")).toInt(&colOk);
- if (!colOk)
+ if (!colOk) {
m_column = -1;
+ }
auto regionName = reader.attributes().value(QLatin1String("beginRegion"));
- if (!regionName.isEmpty())
+ if (!regionName.isEmpty()) {
m_beginRegion = FoldingRegion(FoldingRegion::Begin, DefinitionData::get(m_def.definition())->foldingRegionId(regionName.toString()));
+ }
regionName = reader.attributes().value(QLatin1String("endRegion"));
- if (!regionName.isEmpty())
+ if (!regionName.isEmpty()) {
m_endRegion = FoldingRegion(FoldingRegion::End, DefinitionData::get(m_def.definition())->foldingRegionId(regionName.toString()));
+ }
auto result = doLoad(reader);
- if (m_lookAhead && m_context.isStay())
+ if (m_lookAhead && m_context.isStay()) {
result = false;
+ }
// be done with this rule, skip all subelements, e.g. no longer supported sub-rules
reader.skipCurrentElement();
@@ -184,42 +192,60 @@ void Rule::loadAdditionalWordDelimiters(QXmlStreamReader &reader)
Rule::Ptr Rule::create(QStringView name)
{
- if (name == QLatin1String("AnyChar"))
+ if (name == QLatin1String("AnyChar")) {
return std::make_shared<AnyChar>();
- if (name == QLatin1String("DetectChar"))
+ }
+ if (name == QLatin1String("DetectChar")) {
return std::make_shared<DetectChar>();
- if (name == QLatin1String("Detect2Chars"))
+ }
+ if (name == QLatin1String("Detect2Chars")) {
return std::make_shared<Detect2Char>();
- if (name == QLatin1String("DetectIdentifier"))
+ }
+ if (name == QLatin1String("DetectIdentifier")) {
return std::make_shared<DetectIdentifier>();
- if (name == QLatin1String("DetectSpaces"))
+ }
+ if (name == QLatin1String("DetectSpaces")) {
return std::make_shared<DetectSpaces>();
- if (name == QLatin1String("Float"))
+ }
+ if (name == QLatin1String("Float")) {
return std::make_shared<Float>();
- if (name == QLatin1String("Int"))
+ }
+ if (name == QLatin1String("Int")) {
return std::make_shared<Int>();
- if (name == QLatin1String("HlCChar"))
+ }
+ if (name == QLatin1String("HlCChar")) {
return std::make_shared<HlCChar>();
- if (name == QLatin1String("HlCHex"))
+ }
+ if (name == QLatin1String("HlCHex")) {
return std::make_shared<HlCHex>();
- if (name == QLatin1String("HlCOct"))
+ }
+ if (name == QLatin1String("HlCOct")) {
return std::make_shared<HlCOct>();
- if (name == QLatin1String("HlCStringChar"))
+ }
+ if (name == QLatin1String("HlCStringChar")) {
return std::make_shared<HlCStringChar>();
- if (name == QLatin1String("IncludeRules"))
+ }
+ if (name == QLatin1String("IncludeRules")) {
return std::make_shared<IncludeRules>();
- if (name == QLatin1String("keyword"))
+ }
+ if (name == QLatin1String("keyword")) {
return std::make_shared<KeywordListRule>();
- if (name == QLatin1String("LineContinue"))
+ }
+ if (name == QLatin1String("LineContinue")) {
return std::make_shared<LineContinue>();
- if (name == QLatin1String("RangeDetect"))
+ }
+ if (name == QLatin1String("RangeDetect")) {
return std::make_shared<RangeDetect>();
- if (name == QLatin1String("RegExpr"))
+ }
+ if (name == QLatin1String("RegExpr")) {
return std::make_shared<RegExpr>();
- if (name == QLatin1String("StringDetect"))
+ }
+ if (name == QLatin1String("StringDetect")) {
return std::make_shared<StringDetect>();
- if (name == QLatin1String("WordDetect"))
+ }
+ if (name == QLatin1String("WordDetect")) {
return std::make_shared<WordDetect>();
+ }
qCWarning(Log) << "Unknown rule type:" << name;
return Ptr(nullptr);
@@ -233,23 +259,26 @@ bool Rule::isWordDelimiter(QChar c) const
bool AnyChar::doLoad(QXmlStreamReader &reader)
{
m_chars = reader.attributes().value(QLatin1String("String")).toString();
- if (m_chars.size() == 1)
+ if (m_chars.size() == 1) {
qCDebug(Log) << "AnyChar rule with just one char: use DetectChar instead.";
+ }
return !m_chars.isEmpty();
}
-MatchResult AnyChar::doMatch(const QString &text, int offset, const QStringList &) const
+MatchResult AnyChar::doMatch(QStringView text, int offset, const QStringList &) const
{
- if (m_chars.contains(text.at(offset)))
+ if (m_chars.contains(text.at(offset))) {
return offset + 1;
+ }
return offset;
}
bool DetectChar::doLoad(QXmlStreamReader &reader)
{
const auto s = reader.attributes().value(QLatin1String("char"));
- if (s.isEmpty())
+ if (s.isEmpty()) {
return false;
+ }
m_char = s.at(0);
m_dynamic = Xml::attrToBool(reader.attributes().value(QLatin1String("dynamic")));
if (m_dynamic) {
@@ -258,18 +287,21 @@ bool DetectChar::doLoad(QXmlStreamReader &reader)
return true;
}
-MatchResult DetectChar::doMatch(const QString &text, int offset, const QStringList &captures) const
+MatchResult DetectChar::doMatch(QStringView text, int offset, const QStringList &captures) const
{
if (m_dynamic) {
- if (m_captureIndex == 0 || captures.size() <= m_captureIndex || captures.at(m_captureIndex).isEmpty())
+ if (m_captureIndex == 0 || captures.size() <= m_captureIndex || captures.at(m_captureIndex).isEmpty()) {
return offset;
- if (text.at(offset) == captures.at(m_captureIndex).at(0))
+ }
+ if (text.at(offset) == captures.at(m_captureIndex).at(0)) {
return offset + 1;
+ }
return offset;
}
- if (text.at(offset) == m_char)
+ if (text.at(offset) == m_char) {
return offset + 1;
+ }
return offset;
}
@@ -277,40 +309,46 @@ bool Detect2Char::doLoad(QXmlStreamReader &reader)
{
const auto s1 = reader.attributes().value(QLatin1String("char"));
const auto s2 = reader.attributes().value(QLatin1String("char1"));
- if (s1.isEmpty() || s2.isEmpty())
+ if (s1.isEmpty() || s2.isEmpty()) {
return false;
+ }
m_char1 = s1.at(0);
m_char2 = s2.at(0);
return true;
}
-MatchResult Detect2Char::doMatch(const QString &text, int offset, const QStringList &) const
+MatchResult Detect2Char::doMatch(QStringView text, int offset, const QStringList &) const
{
- if (text.size() - offset < 2)
+ if (text.size() - offset < 2) {
return offset;
- if (text.at(offset) == m_char1 && text.at(offset + 1) == m_char2)
+ }
+ if (text.at(offset) == m_char1 && text.at(offset + 1) == m_char2) {
return offset + 2;
+ }
return offset;
}
-MatchResult DetectIdentifier::doMatch(const QString &text, int offset, const QStringList &) const
+MatchResult DetectIdentifier::doMatch(QStringView text, int offset, const QStringList &) const
{
- if (!text.at(offset).isLetter() && text.at(offset) != QLatin1Char('_'))
+ if (!text.at(offset).isLetter() && text.at(offset) != QLatin1Char('_')) {
return offset;
+ }
for (int i = offset + 1; i < text.size(); ++i) {
const auto c = text.at(i);
- if (!c.isLetterOrNumber() && c != QLatin1Char('_'))
+ if (!c.isLetterOrNumber() && c != QLatin1Char('_')) {
return i;
+ }
}
return text.size();
}
-MatchResult DetectSpaces::doMatch(const QString &text, int offset, const QStringList &) const
+MatchResult DetectSpaces::doMatch(QStringView text, int offset, const QStringList &) const
{
- while (offset < text.size() && text.at(offset).isSpace())
+ while (offset < text.size() && text.at(offset).isSpace()) {
++offset;
+ }
return offset;
}
@@ -320,63 +358,76 @@ bool Float::doLoad(QXmlStreamReader &reader)
return true;
}
-MatchResult Float::doMatch(const QString &text, int offset, const QStringList &) const
+MatchResult Float::doMatch(QStringView text, int offset, const QStringList &) const
{
- if (offset > 0 && !isWordDelimiter(text.at(offset - 1)))
+ if (offset > 0 && !isWordDelimiter(text.at(offset - 1))) {
return offset;
+ }
auto newOffset = offset;
- while (newOffset < text.size() && isDigit(text.at(newOffset)))
+ while (newOffset < text.size() && isDigit(text.at(newOffset))) {
++newOffset;
+ }
- if (newOffset >= text.size() || text.at(newOffset) != QLatin1Char('.'))
+ if (newOffset >= text.size() || text.at(newOffset) != QLatin1Char('.')) {
return offset;
+ }
++newOffset;
- while (newOffset < text.size() && isDigit(text.at(newOffset)))
+ while (newOffset < text.size() && isDigit(text.at(newOffset))) {
++newOffset;
+ }
- if (newOffset == offset + 1) // we only found a decimal point
+ if (newOffset == offset + 1) { // we only found a decimal point
return offset;
+ }
auto expOffset = newOffset;
- if (expOffset >= text.size() || (text.at(expOffset) != QLatin1Char('e') && text.at(expOffset) != QLatin1Char('E')))
+ if (expOffset >= text.size() || (text.at(expOffset) != QLatin1Char('e') && text.at(expOffset) != QLatin1Char('E'))) {
return newOffset;
+ }
++expOffset;
- if (expOffset < text.size() && (text.at(expOffset) == QLatin1Char('+') || text.at(expOffset) == QLatin1Char('-')))
+ if (expOffset < text.size() && (text.at(expOffset) == QLatin1Char('+') || text.at(expOffset) == QLatin1Char('-'))) {
++expOffset;
+ }
bool foundExpDigit = false;
while (expOffset < text.size() && isDigit(text.at(expOffset))) {
++expOffset;
foundExpDigit = true;
}
- if (!foundExpDigit)
+ if (!foundExpDigit) {
return newOffset;
+ }
return expOffset;
}
-MatchResult HlCChar::doMatch(const QString &text, int offset, const QStringList &) const
+MatchResult HlCChar::doMatch(QStringView text, int offset, const QStringList &) const
{
- if (text.size() < offset + 3)
+ if (text.size() < offset + 3) {
return offset;
+ }
- if (text.at(offset) != QLatin1Char('\'') || text.at(offset + 1) == QLatin1Char('\''))
+ if (text.at(offset) != QLatin1Char('\'') || text.at(offset + 1) == QLatin1Char('\'')) {
return offset;
+ }
auto newOffset = matchEscapedChar(text, offset + 1);
if (newOffset == offset + 1) {
- if (text.at(newOffset) == QLatin1Char('\\'))
+ if (text.at(newOffset) == QLatin1Char('\\')) {
return offset;
- else
+ } else {
++newOffset;
+ }
}
- if (newOffset >= text.size())
+ if (newOffset >= text.size()) {
return offset;
+ }
- if (text.at(newOffset) == QLatin1Char('\''))
+ if (text.at(newOffset) == QLatin1Char('\'')) {
return newOffset + 1;
+ }
return offset;
}
@@ -387,23 +438,28 @@ bool HlCHex::doLoad(QXmlStreamReader &reader)
return true;
}
-MatchResult HlCHex::doMatch(const QString &text, int offset, const QStringList &) const
+MatchResult HlCHex::doMatch(QStringView text, int offset, const QStringList &) const
{
- if (offset > 0 && !isWordDelimiter(text.at(offset - 1)))
+ if (offset > 0 && !isWordDelimiter(text.at(offset - 1))) {
return offset;
+ }
- if (text.size() < offset + 3)
+ if (text.size() < offset + 3) {
return offset;
+ }
- if (text.at(offset) != QLatin1Char('0') || (text.at(offset + 1) != QLatin1Char('x') && text.at(offset + 1) != QLatin1Char('X')))
+ if (text.at(offset) != QLatin1Char('0') || (text.at(offset + 1) != QLatin1Char('x') && text.at(offset + 1) != QLatin1Char('X'))) {
return offset;
+ }
- if (!isHexChar(text.at(offset + 2)))
+ if (!isHexChar(text.at(offset + 2))) {
return offset;
+ }
offset += 3;
- while (offset < text.size() && isHexChar(text.at(offset)))
+ while (offset < text.size() && isHexChar(text.at(offset))) {
++offset;
+ }
// TODO Kate matches U/L suffix, QtC does not?
@@ -416,28 +472,33 @@ bool HlCOct::doLoad(QXmlStreamReader &reader)
return true;
}
-MatchResult HlCOct::doMatch(const QString &text, int offset, const QStringList &) const
+MatchResult HlCOct::doMatch(QStringView text, int offset, const QStringList &) const
{
- if (offset > 0 && !isWordDelimiter(text.at(offset - 1)))
+ if (offset > 0 && !isWordDelimiter(text.at(offset - 1))) {
return offset;
+ }
- if (text.size() < offset + 2)
+ if (text.size() < offset + 2) {
return offset;
+ }
- if (text.at(offset) != QLatin1Char('0'))
+ if (text.at(offset) != QLatin1Char('0')) {
return offset;
+ }
- if (!isOctalChar(text.at(offset + 1)))
+ if (!isOctalChar(text.at(offset + 1))) {
return offset;
+ }
offset += 2;
- while (offset < text.size() && isOctalChar(text.at(offset)))
+ while (offset < text.size() && isOctalChar(text.at(offset))) {
++offset;
+ }
return offset;
}
-MatchResult HlCStringChar::doMatch(const QString &text, int offset, const QStringList &) const
+MatchResult HlCStringChar::doMatch(QStringView text, int offset, const QStringList &) const
{
return matchEscapedChar(text, offset);
}
@@ -461,17 +522,19 @@ bool IncludeRules::doLoad(QXmlStreamReader &reader)
{
const auto s = reader.attributes().value(QLatin1String("context"));
const auto split = s.split(QString::fromLatin1("##"), Qt::KeepEmptyParts);
- if (split.isEmpty())
+ if (split.isEmpty()) {
return false;
+ }
m_contextName = split.at(0).toString();
- if (split.size() > 1)
+ if (split.size() > 1) {
m_defName = split.at(1).toString();
+ }
m_includeAttribute = Xml::attrToBool(reader.attributes().value(QLatin1String("includeAttrib")));
return !m_contextName.isEmpty() || !m_defName.isEmpty();
}
-MatchResult IncludeRules::doMatch(const QString &text, int offset, const QStringList &) const
+MatchResult IncludeRules::doMatch(QStringView text, int offset, const QStringList &) const
{
Q_UNUSED(text);
qCWarning(Log) << "Unresolved include rule for" << m_contextName << "##" << m_defName;
@@ -484,13 +547,15 @@ bool Int::doLoad(QXmlStreamReader &reader)
return true;
}
-MatchResult Int::doMatch(const QString &text, int offset, const QStringList &) const
+MatchResult Int::doMatch(QStringView text, int offset, const QStringList &) const
{
- if (offset > 0 && !isWordDelimiter(text.at(offset - 1)))
+ if (offset > 0 && !isWordDelimiter(text.at(offset - 1))) {
return offset;
+ }
- while (offset < text.size() && isDigit(text.at(offset)))
+ while (offset < text.size() && isDigit(text.at(offset))) {
++offset;
+ }
return offset;
}
@@ -522,21 +587,24 @@ bool KeywordListRule::doLoad(QXmlStreamReader &reader)
return !m_keywordList->isEmpty();
}
-MatchResult KeywordListRule::doMatch(const QString &text, int offset, const QStringList &) const
+MatchResult KeywordListRule::doMatch(QStringView text, int offset, const QStringList &) const
{
auto newOffset = offset;
- while (text.size() > newOffset && !isWordDelimiter(text.at(newOffset)))
+ while (text.size() > newOffset && !isWordDelimiter(text.at(newOffset))) {
++newOffset;
- if (newOffset == offset)
+ }
+ if (newOffset == offset) {
return offset;
+ }
if (m_hasCaseSensitivityOverride) {
- if (m_keywordList->contains(QStringView(text).mid(offset, newOffset - offset),
- m_caseSensitivityOverride))
+ if (m_keywordList->contains(text.mid(offset, newOffset - offset), m_caseSensitivityOverride)) {
return newOffset;
+ }
} else {
- if (m_keywordList->contains(QStringView(text).mid(offset, newOffset - offset)))
+ if (m_keywordList->contains(text.mid(offset, newOffset - offset))) {
return newOffset;
+ }
}
// we don't match, but we can skip until newOffset as we can't start a keyword in-between
@@ -546,17 +614,19 @@ MatchResult KeywordListRule::doMatch(const QString &text, int offset, const QStr
bool LineContinue::doLoad(QXmlStreamReader &reader)
{
const auto s = reader.attributes().value(QLatin1String("char"));
- if (s.isEmpty())
+ if (s.isEmpty()) {
m_char = QLatin1Char('\\');
- else
+ } else {
m_char = s.at(0);
+ }
return true;
}
-MatchResult LineContinue::doMatch(const QString &text, int offset, const QStringList &) const
+MatchResult LineContinue::doMatch(QStringView text, int offset, const QStringList &) const
{
- if (offset == text.size() - 1 && text.at(offset) == m_char)
+ if (offset == text.size() - 1 && text.at(offset) == m_char) {
return offset + 1;
+ }
return offset;
}
@@ -564,24 +634,28 @@ bool RangeDetect::doLoad(QXmlStreamReader &reader)
{
const auto s1 = reader.attributes().value(QLatin1String("char"));
const auto s2 = reader.attributes().value(QLatin1String("char1"));
- if (s1.isEmpty() || s2.isEmpty())
+ if (s1.isEmpty() || s2.isEmpty()) {
return false;
+ }
m_begin = s1.at(0);
m_end = s2.at(0);
return true;
}
-MatchResult RangeDetect::doMatch(const QString &text, int offset, const QStringList &) const
+MatchResult RangeDetect::doMatch(QStringView text, int offset, const QStringList &) const
{
- if (text.size() - offset < 2)
+ if (text.size() - offset < 2) {
return offset;
- if (text.at(offset) != m_begin)
+ }
+ if (text.at(offset) != m_begin) {
return offset;
+ }
auto newOffset = offset + 1;
while (newOffset < text.size()) {
- if (text.at(newOffset) == m_end)
+ if (text.at(newOffset) == m_end) {
return newOffset + 1;
+ }
++newOffset;
}
return offset;
@@ -596,7 +670,9 @@ bool RegExpr::doLoad(QXmlStreamReader &reader)
m_regexp.setPatternOptions((isMinimal ? QRegularExpression::InvertedGreedinessOption : QRegularExpression::NoPatternOption)
| (isCaseInsensitive ? QRegularExpression::CaseInsensitiveOption : QRegularExpression::NoPatternOption)
// DontCaptureOption is removed by resolvePostProcessing() when necessary
- | QRegularExpression::DontCaptureOption);
+ | QRegularExpression::DontCaptureOption
+ // ensure Unicode support is enabled
+ | QRegularExpression::UseUnicodePropertiesOption);
m_dynamic = Xml::attrToBool(reader.attributes().value(QLatin1String("dynamic")));
@@ -605,8 +681,9 @@ bool RegExpr::doLoad(QXmlStreamReader &reader)
void KSyntaxHighlighting::RegExpr::resolvePostProcessing()
{
- if (m_isResolved)
+ if (m_isResolved) {
return;
+ }
m_isResolved = true;
bool hasCapture = false;
@@ -641,7 +718,7 @@ void KSyntaxHighlighting::RegExpr::resolvePostProcessing()
}
}
-MatchResult RegExpr::doMatch(const QString &text, int offset, const QStringList &captures) const
+MatchResult RegExpr::doMatch(QStringView text, int offset, const QStringList &captures) const
{
/**
* for dynamic case: create new pattern with right instantiation
@@ -651,7 +728,11 @@ MatchResult RegExpr::doMatch(const QString &text, int offset, const QStringList
/**
* match the pattern
*/
+#if QT_VERSION < QT_VERSION_CHECK(5, 15, 2)
+ const auto result = regexp.match(text.toString(), offset, QRegularExpression::NormalMatch, QRegularExpression::DontCheckSubjectStringMatchOption);
+#else
const auto result = regexp.match(text, offset, QRegularExpression::NormalMatch, QRegularExpression::DontCheckSubjectStringMatchOption);
+#endif
if (result.capturedStart() == offset) {
/**
* we only need to compute the captured texts if we have real capture groups
@@ -683,16 +764,16 @@ bool StringDetect::doLoad(QXmlStreamReader &reader)
return !m_string.isEmpty();
}
-MatchResult StringDetect::doMatch(const QString &text, int offset, const QStringList &captures) const
+MatchResult StringDetect::doMatch(QStringView text, int offset, const QStringList &captures) const
{
/**
* for dynamic case: create new pattern with right instantiation
*/
const auto &pattern = m_dynamic ? replaceCaptures(m_string, captures, false) : m_string;
- if (offset + pattern.size() <= text.size()
- && QStringView(text).mid(offset, pattern.size()).compare(pattern, m_caseSensitivity) == 0)
+ if (offset + pattern.size() <= text.size() && text.mid(offset, pattern.size()).compare(pattern, m_caseSensitivity) == 0) {
return offset + pattern.size();
+ }
return offset;
}
@@ -704,23 +785,27 @@ bool WordDetect::doLoad(QXmlStreamReader &reader)
return !m_word.isEmpty();
}
-MatchResult WordDetect::doMatch(const QString &text, int offset, const QStringList &) const
+MatchResult WordDetect::doMatch(QStringView text, int offset, const QStringList &) const
{
- if (text.size() - offset < m_word.size())
+ if (text.size() - offset < m_word.size()) {
return offset;
+ }
/**
* detect delimiter characters on the inner and outer boundaries of the string
* NOTE: m_word isn't empty
*/
- if (offset > 0 && !isWordDelimiter(text.at(offset - 1)) && !isWordDelimiter(text.at(offset)))
+ if (offset > 0 && !isWordDelimiter(text.at(offset - 1)) && !isWordDelimiter(text.at(offset))) {
return offset;
+ }
- if (QStringView(text).mid(offset, m_word.size()).compare(m_word, m_caseSensitivity) != 0)
+ if (text.mid(offset, m_word.size()).compare(m_word, m_caseSensitivity) != 0) {
return offset;
+ }
- if (text.size() == offset + m_word.size() || isWordDelimiter(text.at(offset + m_word.size())) || isWordDelimiter(text.at(offset + m_word.size() - 1)))
+ if (text.size() == offset + m_word.size() || isWordDelimiter(text.at(offset + m_word.size())) || isWordDelimiter(text.at(offset + m_word.size() - 1))) {
return offset + m_word.size();
+ }
return offset;
}
diff --git a/src/libs/3rdparty/syntax-highlighting/src/lib/rule_p.h b/src/libs/3rdparty/syntax-highlighting/src/lib/rule_p.h
index 22c786eaa2..374eb87dfa 100644
--- a/src/libs/3rdparty/syntax-highlighting/src/lib/rule_p.h
+++ b/src/libs/3rdparty/syntax-highlighting/src/lib/rule_p.h
@@ -87,7 +87,7 @@ public:
{
}
- virtual MatchResult doMatch(const QString &text, int offset, const QStringList &captures) const = 0;
+ virtual MatchResult doMatch(QStringView text, int offset, const QStringList &captures) const = 0;
static Rule::Ptr create(QStringView name);
@@ -121,58 +121,58 @@ protected:
bool m_dynamic = false;
};
-class AnyChar : public Rule
+class AnyChar final : public Rule
{
protected:
bool doLoad(QXmlStreamReader &reader) override;
- MatchResult doMatch(const QString &text, int offset, const QStringList &) const override;
+ MatchResult doMatch(QStringView text, int offset, const QStringList &) const override;
private:
QString m_chars;
};
-class DetectChar : public Rule
+class DetectChar final : public Rule
{
protected:
bool doLoad(QXmlStreamReader &reader) override;
- MatchResult doMatch(const QString &text, int offset, const QStringList &captures) const override;
+ MatchResult doMatch(QStringView text, int offset, const QStringList &captures) const override;
private:
QChar m_char;
int m_captureIndex = 0;
};
-class Detect2Char : public Rule
+class Detect2Char final : public Rule
{
protected:
bool doLoad(QXmlStreamReader &reader) override;
- MatchResult doMatch(const QString &text, int offset, const QStringList &captures) const override;
+ MatchResult doMatch(QStringView text, int offset, const QStringList &captures) const override;
private:
QChar m_char1;
QChar m_char2;
};
-class DetectIdentifier : public Rule
+class DetectIdentifier final : public Rule
{
protected:
- MatchResult doMatch(const QString &text, int offset, const QStringList &) const override;
+ MatchResult doMatch(QStringView text, int offset, const QStringList &) const override;
};
-class DetectSpaces : public Rule
+class DetectSpaces final : public Rule
{
protected:
- MatchResult doMatch(const QString &text, int offset, const QStringList &) const override;
+ MatchResult doMatch(QStringView text, int offset, const QStringList &) const override;
};
-class Float : public Rule
+class Float final : public Rule
{
protected:
bool doLoad(QXmlStreamReader &reader) override;
- MatchResult doMatch(const QString &text, int offset, const QStringList &) const override;
+ MatchResult doMatch(QStringView text, int offset, const QStringList &) const override;
};
-class IncludeRules : public Rule
+class IncludeRules final : public Rule
{
public:
QString contextName() const;
@@ -181,7 +181,7 @@ public:
protected:
bool doLoad(QXmlStreamReader &reader) override;
- MatchResult doMatch(const QString &text, int offset, const QStringList &) const override;
+ MatchResult doMatch(QStringView text, int offset, const QStringList &) const override;
private:
QString m_contextName;
@@ -189,44 +189,44 @@ private:
bool m_includeAttribute;
};
-class Int : public Rule
+class Int final : public Rule
{
protected:
bool doLoad(QXmlStreamReader &reader) override;
- MatchResult doMatch(const QString &text, int offset, const QStringList &captures) const override;
+ MatchResult doMatch(QStringView text, int offset, const QStringList &captures) const override;
};
-class HlCChar : public Rule
+class HlCChar final : public Rule
{
protected:
- MatchResult doMatch(const QString &text, int offset, const QStringList &) const override;
+ MatchResult doMatch(QStringView text, int offset, const QStringList &) const override;
};
-class HlCHex : public Rule
+class HlCHex final : public Rule
{
protected:
bool doLoad(QXmlStreamReader &reader) override;
- MatchResult doMatch(const QString &text, int offset, const QStringList &) const override;
+ MatchResult doMatch(QStringView text, int offset, const QStringList &) const override;
};
-class HlCOct : public Rule
+class HlCOct final : public Rule
{
protected:
bool doLoad(QXmlStreamReader &reader) override;
- MatchResult doMatch(const QString &text, int offset, const QStringList &) const override;
+ MatchResult doMatch(QStringView text, int offset, const QStringList &) const override;
};
-class HlCStringChar : public Rule
+class HlCStringChar final : public Rule
{
protected:
- MatchResult doMatch(const QString &text, int offset, const QStringList &) const override;
+ MatchResult doMatch(QStringView text, int offset, const QStringList &) const override;
};
-class KeywordListRule : public Rule
+class KeywordListRule final : public Rule
{
protected:
bool doLoad(QXmlStreamReader &reader) override;
- MatchResult doMatch(const QString &text, int offset, const QStringList &) const override;
+ MatchResult doMatch(QStringView text, int offset, const QStringList &) const override;
private:
KeywordList *m_keywordList;
@@ -234,55 +234,55 @@ private:
Qt::CaseSensitivity m_caseSensitivityOverride;
};
-class LineContinue : public Rule
+class LineContinue final : public Rule
{
protected:
bool doLoad(QXmlStreamReader &reader) override;
- MatchResult doMatch(const QString &text, int offset, const QStringList &) const override;
+ MatchResult doMatch(QStringView text, int offset, const QStringList &) const override;
private:
QChar m_char;
};
-class RangeDetect : public Rule
+class RangeDetect final : public Rule
{
protected:
bool doLoad(QXmlStreamReader &reader) override;
- MatchResult doMatch(const QString &text, int offset, const QStringList &) const override;
+ MatchResult doMatch(QStringView text, int offset, const QStringList &) const override;
private:
QChar m_begin;
QChar m_end;
};
-class RegExpr : public Rule
+class RegExpr final : public Rule
{
protected:
void resolvePostProcessing() override;
bool doLoad(QXmlStreamReader &reader) override;
- MatchResult doMatch(const QString &text, int offset, const QStringList &captures) const override;
+ MatchResult doMatch(QStringView text, int offset, const QStringList &captures) const override;
private:
QRegularExpression m_regexp;
bool m_isResolved = false;
};
-class StringDetect : public Rule
+class StringDetect final : public Rule
{
protected:
bool doLoad(QXmlStreamReader &reader) override;
- MatchResult doMatch(const QString &text, int offset, const QStringList &captures) const override;
+ MatchResult doMatch(QStringView text, int offset, const QStringList &captures) const override;
private:
QString m_string;
Qt::CaseSensitivity m_caseSensitivity;
};
-class WordDetect : public Rule
+class WordDetect final : public Rule
{
protected:
bool doLoad(QXmlStreamReader &reader) override;
- MatchResult doMatch(const QString &text, int offset, const QStringList &captures) const override;
+ MatchResult doMatch(QStringView text, int offset, const QStringList &captures) const override;
private:
QString m_word;
diff --git a/src/libs/3rdparty/syntax-highlighting/src/lib/state.cpp b/src/libs/3rdparty/syntax-highlighting/src/lib/state.cpp
index f9b4f4b4ab..ea21fef215 100644
--- a/src/libs/3rdparty/syntax-highlighting/src/lib/state.cpp
+++ b/src/libs/3rdparty/syntax-highlighting/src/lib/state.cpp
@@ -104,7 +104,8 @@ bool State::operator!=(const State &other) const
bool State::indentationBasedFoldingEnabled() const
{
- if (!d || d->m_contextStack.isEmpty())
+ if (!d || d->m_contextStack.isEmpty()) {
return false;
+ }
return d->m_contextStack.last().first->indentationBasedFoldingEnabled();
}
diff --git a/src/libs/3rdparty/syntax-highlighting/src/lib/syntaxhighlighter.cpp b/src/libs/3rdparty/syntax-highlighting/src/lib/syntaxhighlighter.cpp
index d0c4ee98ae..41551e96da 100644
--- a/src/libs/3rdparty/syntax-highlighting/src/lib/syntaxhighlighter.cpp
+++ b/src/libs/3rdparty/syntax-highlighting/src/lib/syntaxhighlighter.cpp
@@ -37,11 +37,13 @@ public:
FoldingRegion SyntaxHighlighterPrivate::foldingRegion(const QTextBlock &startBlock)
{
const auto data = dynamic_cast<TextBlockUserData *>(startBlock.userData());
- if (!data)
+ if (!data) {
return FoldingRegion();
+ }
for (int i = data->foldingRegions.size() - 1; i >= 0; --i) {
- if (data->foldingRegions.at(i).type() == FoldingRegion::Begin)
+ if (data->foldingRegions.at(i).type() == FoldingRegion::Begin) {
return data->foldingRegions.at(i);
+ }
}
return FoldingRegion();
}
@@ -68,8 +70,9 @@ void SyntaxHighlighter::setDefinition(const Definition &def)
{
const auto needsRehighlight = definition() != def;
AbstractHighlighter::setDefinition(def);
- if (needsRehighlight)
+ if (needsRehighlight) {
rehighlight();
+ }
}
bool SyntaxHighlighter::startsFoldingRegion(const QTextBlock &startBlock) const
@@ -86,17 +89,21 @@ QTextBlock SyntaxHighlighter::findFoldingRegionEnd(const QTextBlock &startBlock)
while (block.isValid()) {
block = block.next();
const auto data = dynamic_cast<TextBlockUserData *>(block.userData());
- if (!data)
+ if (!data) {
continue;
+ }
for (auto it = data->foldingRegions.constBegin(); it != data->foldingRegions.constEnd(); ++it) {
- if ((*it).id() != region.id())
+ if ((*it).id() != region.id()) {
continue;
- if ((*it).type() == FoldingRegion::End)
+ }
+ if ((*it).type() == FoldingRegion::End) {
--depth;
- else if ((*it).type() == FoldingRegion::Begin)
+ } else if ((*it).type() == FoldingRegion::Begin) {
++depth;
- if (depth == 0)
+ }
+ if (depth == 0) {
return block;
+ }
}
}
@@ -111,8 +118,9 @@ void SyntaxHighlighter::highlightBlock(const QString &text)
if (currentBlock().position() > 0) {
const auto prevBlock = currentBlock().previous();
const auto prevData = dynamic_cast<TextBlockUserData *>(prevBlock.userData());
- if (prevData)
+ if (prevData) {
state = prevData->state;
+ }
}
d->foldingRegions.clear();
state = highlightLine(text, state);
@@ -126,35 +134,43 @@ void SyntaxHighlighter::highlightBlock(const QString &text)
return;
}
- if (data->state == state && data->foldingRegions == d->foldingRegions) // we ended up in the same state, so we are done here
+ if (data->state == state && data->foldingRegions == d->foldingRegions) { // we ended up in the same state, so we are done here
return;
+ }
data->state = state;
data->foldingRegions = d->foldingRegions;
const auto nextBlock = currentBlock().next();
- if (nextBlock.isValid())
+ if (nextBlock.isValid()) {
QMetaObject::invokeMethod(this, "rehighlightBlock", Qt::QueuedConnection, Q_ARG(QTextBlock, nextBlock));
+ }
}
void SyntaxHighlighter::applyFormat(int offset, int length, const KSyntaxHighlighting::Format &format)
{
- if (length == 0)
+ if (length == 0) {
return;
+ }
QTextCharFormat tf;
// always set the foreground color to avoid palette issues
tf.setForeground(format.textColor(theme()));
- if (format.hasBackgroundColor(theme()))
+ if (format.hasBackgroundColor(theme())) {
tf.setBackground(format.backgroundColor(theme()));
- if (format.isBold(theme()))
+ }
+ if (format.isBold(theme())) {
tf.setFontWeight(QFont::Bold);
- if (format.isItalic(theme()))
+ }
+ if (format.isItalic(theme())) {
tf.setFontItalic(true);
- if (format.isUnderline(theme()))
+ }
+ if (format.isUnderline(theme())) {
tf.setFontUnderline(true);
- if (format.isStrikeThrough(theme()))
+ }
+ if (format.isStrikeThrough(theme())) {
tf.setFontStrikeOut(true);
+ }
QSyntaxHighlighter::setFormat(offset, length, tf);
}
@@ -165,13 +181,15 @@ void SyntaxHighlighter::applyFolding(int offset, int length, FoldingRegion regio
Q_UNUSED(length);
Q_D(SyntaxHighlighter);
- if (region.type() == FoldingRegion::Begin)
+ if (region.type() == FoldingRegion::Begin) {
d->foldingRegions.push_back(region);
+ }
if (region.type() == FoldingRegion::End) {
for (int i = d->foldingRegions.size() - 1; i >= 0; --i) {
- if (d->foldingRegions.at(i).id() != region.id() || d->foldingRegions.at(i).type() != FoldingRegion::Begin)
+ if (d->foldingRegions.at(i).id() != region.id() || d->foldingRegions.at(i).type() != FoldingRegion::Begin) {
continue;
+ }
d->foldingRegions.remove(i);
return;
}
diff --git a/src/libs/3rdparty/syntax-highlighting/src/lib/theme.h b/src/libs/3rdparty/syntax-highlighting/src/lib/theme.h
index 076e8d0318..37f9de1694 100644
--- a/src/libs/3rdparty/syntax-highlighting/src/lib/theme.h
+++ b/src/libs/3rdparty/syntax-highlighting/src/lib/theme.h
@@ -64,6 +64,8 @@ class RepositoryPrivate;
class KSYNTAXHIGHLIGHTING_EXPORT Theme
{
Q_GADGET
+ Q_PROPERTY(QString name READ name)
+ Q_PROPERTY(QString translatedName READ translatedName)
public:
// TODO KF6:
// - make TextStyle an enum class
diff --git a/src/libs/3rdparty/syntax-highlighting/src/lib/themedata.cpp b/src/libs/3rdparty/syntax-highlighting/src/lib/themedata.cpp
index 2919a31a6e..f9c386bc2a 100644
--- a/src/libs/3rdparty/syntax-highlighting/src/lib/themedata.cpp
+++ b/src/libs/3rdparty/syntax-highlighting/src/lib/themedata.cpp
@@ -160,8 +160,9 @@ bool ThemeData::load(const QString &filePath)
for (auto it = customStyles.begin(); it != customStyles.end(); ++it) {
const auto obj = it.value().toObject();
auto &overrideStyle = m_textStyleOverrides[it.key()];
- for (auto it2 = obj.begin(); it2 != obj.end(); ++it2)
+ for (auto it2 = obj.begin(); it2 != obj.end(); ++it2) {
overrideStyle.insert(it2.key(), readThemeData(it2.value().toObject()));
+ }
}
return true;
diff --git a/src/libs/3rdparty/syntax-highlighting/src/lib/wildcardmatcher.cpp b/src/libs/3rdparty/syntax-highlighting/src/lib/wildcardmatcher.cpp
index 82d3e4ea80..98daff19d6 100644
--- a/src/libs/3rdparty/syntax-highlighting/src/lib/wildcardmatcher.cpp
+++ b/src/libs/3rdparty/syntax-highlighting/src/lib/wildcardmatcher.cpp
@@ -4,14 +4,16 @@
SPDX-License-Identifier: MIT
*/
-#include "wildcardmatcher_p.h"
+#include "wildcardmatcher.h"
using namespace KSyntaxHighlighting;
#include <QChar>
-#include <QString>
+#include <QStringView>
-static bool exactMatch(const QString &candidate, const QString &wildcard, int candidatePosFromRight, int wildcardPosFromRight, bool caseSensitive = true)
+namespace
+{
+bool wildcardMatch(QStringView candidate, QStringView wildcard, int candidatePosFromRight, int wildcardPosFromRight)
{
for (; wildcardPosFromRight >= 0; wildcardPosFromRight--) {
const auto ch = wildcard.at(wildcardPosFromRight).unicode();
@@ -27,7 +29,7 @@ static bool exactMatch(const QString &candidate, const QString &wildcard, int ca
// Eat all we can and go back as far as we have to
for (int j = -1; j <= candidatePosFromRight; j++) {
- if (exactMatch(candidate, wildcard, j, wildcardPosFromRight - 1)) {
+ if (wildcardMatch(candidate, wildcard, j, wildcardPosFromRight - 1)) {
return true;
}
}
@@ -47,18 +49,19 @@ static bool exactMatch(const QString &candidate, const QString &wildcard, int ca
}
const auto candidateCh = candidate.at(candidatePosFromRight).unicode();
- const auto match = caseSensitive ? (candidateCh == ch) : (QChar::toLower(candidateCh) == QChar::toLower(ch));
- if (match) {
+ if (candidateCh == ch) {
candidatePosFromRight--;
} else {
return false;
}
}
}
- return true;
+ return candidatePosFromRight == -1;
}
-bool WildcardMatcher::exactMatch(const QString &candidate, const QString &wildcard, bool caseSensitive)
+} // unnamed namespace
+
+bool WildcardMatcher::exactMatch(QStringView candidate, QStringView wildcard)
{
- return ::exactMatch(candidate, wildcard, candidate.length() - 1, wildcard.length() - 1, caseSensitive);
+ return ::wildcardMatch(candidate, wildcard, candidate.length() - 1, wildcard.length() - 1);
}
diff --git a/src/libs/3rdparty/syntax-highlighting/src/lib/wildcardmatcher.h b/src/libs/3rdparty/syntax-highlighting/src/lib/wildcardmatcher.h
new file mode 100644
index 0000000000..4042de3788
--- /dev/null
+++ b/src/libs/3rdparty/syntax-highlighting/src/lib/wildcardmatcher.h
@@ -0,0 +1,33 @@
+/*
+ SPDX-FileCopyrightText: 2007 Sebastian Pipping <webmaster@hartwork.org>
+
+ SPDX-License-Identifier: MIT
+*/
+
+#ifndef KSYNTAXHIGHLIGHTING_WILDCARDMATCHER_H
+#define KSYNTAXHIGHLIGHTING_WILDCARDMATCHER_H
+
+#include "ksyntaxhighlighting_export.h"
+
+#include <QStringView>
+
+namespace KSyntaxHighlighting
+{
+namespace WildcardMatcher
+{
+/**
+ * Matches a string against a given wildcard case-sensitively.
+ * The wildcard supports '*' (".*" in regex) and '?' ("." in regex), not more.
+ *
+ * @param candidate Text to match
+ * @param wildcard Wildcard to use
+ * @return True for an exact match, false otherwise
+ *
+ * @since 5.86
+ */
+KSYNTAXHIGHLIGHTING_EXPORT bool exactMatch(QStringView candidate, QStringView wildcard);
+}
+
+}
+
+#endif // KSYNTAXHIGHLIGHTING_WILDCARDMATCHER_H
diff --git a/src/libs/3rdparty/syntax-highlighting/src/lib/worddelimiters.cpp b/src/libs/3rdparty/syntax-highlighting/src/lib/worddelimiters.cpp
index 634eeb70bb..f9079ea1f3 100644
--- a/src/libs/3rdparty/syntax-highlighting/src/lib/worddelimiters.cpp
+++ b/src/libs/3rdparty/syntax-highlighting/src/lib/worddelimiters.cpp
@@ -11,15 +11,17 @@ using namespace KSyntaxHighlighting;
WordDelimiters::WordDelimiters()
: asciiDelimiters{}
{
- for (const char *p = "\t !%&()*+,-./:;<=>?[\\]^{|}~"; *p; ++p)
+ for (const char *p = "\t !%&()*+,-./:;<=>?[\\]^{|}~"; *p; ++p) {
// int(*p) fix -Wchar-subscripts
asciiDelimiters[int(*p)] = true;
+ }
}
bool WordDelimiters::contains(QChar c) const
{
- if (c.unicode() < 128)
+ if (c.unicode() < 128) {
return asciiDelimiters[c.unicode()];
+ }
// perf tells contains is MUCH faster than binary search here, very short array
return notAsciiDelimiters.contains(c);
}
diff --git a/src/libs/3rdparty/syntax-highlighting/src/lib/worddelimiters_p.h b/src/libs/3rdparty/syntax-highlighting/src/lib/worddelimiters_p.h
index 3fa5db10a4..c1afaaa6bb 100644
--- a/src/libs/3rdparty/syntax-highlighting/src/lib/worddelimiters_p.h
+++ b/src/libs/3rdparty/syntax-highlighting/src/lib/worddelimiters_p.h
@@ -12,7 +12,7 @@
namespace KSyntaxHighlighting
{
/**
- * Repesents a list of character that separates 2 words.
+ * Represents a list of character that separates 2 words.
*
* Default delimiters are .():!+*,-<=>%&/;?[]^{|}~\, space (' ') and tabulator ('\t').
*
diff --git a/src/libs/3rdparty/syntax-highlighting/src/lib/xml_p.h b/src/libs/3rdparty/syntax-highlighting/src/lib/xml_p.h
index 5aae9eebb5..2e1dd25cc8 100644
--- a/src/libs/3rdparty/syntax-highlighting/src/lib/xml_p.h
+++ b/src/libs/3rdparty/syntax-highlighting/src/lib/xml_p.h
@@ -17,7 +17,7 @@ namespace Xml
/** Parse a xs:boolean attribute. */
inline bool attrToBool(QStringView str)
{
- return str == QLatin1String("1") || str.compare(QString("true"), Qt::CaseInsensitive) == 0;
+ return str == QStringLiteral("1") || str.compare(QStringLiteral("true"), Qt::CaseInsensitive) == 0;
}
}
diff --git a/src/libs/3rdparty/syntax-highlighting/syntax-highlighting.pro b/src/libs/3rdparty/syntax-highlighting/syntax-highlighting.pro
index 333af297a8..e9354a2f69 100644
--- a/src/libs/3rdparty/syntax-highlighting/syntax-highlighting.pro
+++ b/src/libs/3rdparty/syntax-highlighting/syntax-highlighting.pro
@@ -3,7 +3,7 @@ include(autogenerated/autogenerated.pri)
QT += network
-DEFINES += KSYNTAXHIGHLIGHTING_LIBRARY
+DEFINES += KF5SyntaxHighlighting_EXPORTS
RESOURCES += \
data/themes/theme-data.qrc
diff --git a/src/libs/3rdparty/syntax-highlighting/syntax-highlighting.qbs b/src/libs/3rdparty/syntax-highlighting/syntax-highlighting.qbs
index 27b5987e1a..985264440f 100644
--- a/src/libs/3rdparty/syntax-highlighting/syntax-highlighting.qbs
+++ b/src/libs/3rdparty/syntax-highlighting/syntax-highlighting.qbs
@@ -25,7 +25,7 @@ Project {
name: "KSyntaxHighlighting_bundled"
condition: !qtc.preferSystemSyntaxHighlighting || !Qt.KSyntaxHighlighting.present
- cpp.defines: base.concat("KSYNTAXHIGHLIGHTING_LIBRARY")
+ cpp.defines: base.concat("KF5SyntaxHighlighting_EXPORTS")
cpp.includePaths: [
product.sourceDirectory + "/src/lib/",
product.sourceDirectory + "/autogenerated/src/lib/",
@@ -66,7 +66,6 @@ Project {
"htmlhighlighter.h",
"keywordlist.cpp",
"keywordlist_p.h",
- "ksyntaxhighlighting_export.h",
"matchresult_p.h",
"repository.cpp",
"repository.h",
diff --git a/src/libs/cplusplus/LookupContext.cpp b/src/libs/cplusplus/LookupContext.cpp
index 5eaa04baf4..3f7e791115 100644
--- a/src/libs/cplusplus/LookupContext.cpp
+++ b/src/libs/cplusplus/LookupContext.cpp
@@ -38,6 +38,7 @@
#include <cplusplus/Control.h>
#include <utils/algorithm.h>
+#include <utils/porting.h>
#include <QStack>
#include <QHash>
@@ -150,9 +151,9 @@ bool operator==(const FullyQualifiedName &left, const FullyQualifiedName &right)
return compareFullyQualifiedName(left.fqn, right.fqn);
}
-uint qHash(const FullyQualifiedName &fullyQualifiedName)
+Utils::QHashValueType qHash(const FullyQualifiedName &fullyQualifiedName)
{
- uint h = 0;
+ Utils::QHashValueType h = 0;
for (int i = 0; i < fullyQualifiedName.fqn.size(); ++i) {
if (const Name *n = fullyQualifiedName.fqn.at(i)) {
if (const Identifier *id = n->identifier()) {
diff --git a/src/libs/cplusplus/LookupItem.cpp b/src/libs/cplusplus/LookupItem.cpp
index 7fc73ba240..f4fce6e4ed 100644
--- a/src/libs/cplusplus/LookupItem.cpp
+++ b/src/libs/cplusplus/LookupItem.cpp
@@ -33,10 +33,10 @@
using namespace CPlusPlus;
-uint CPlusPlus::qHash(const LookupItem &key)
+Utils::QHashValueType CPlusPlus::qHash(const LookupItem &key)
{
- const uint h1 = QT_PREPEND_NAMESPACE(qHash)(key.type().type());
- const uint h2 = QT_PREPEND_NAMESPACE(qHash)(key.scope());
+ const Utils::QHashValueType h1 = QT_PREPEND_NAMESPACE(qHash)(key.type().type());
+ const Utils::QHashValueType h2 = QT_PREPEND_NAMESPACE(qHash)(key.scope());
return ((h1 << 16) | (h1 >> 16)) ^ h2;
}
diff --git a/src/libs/cplusplus/LookupItem.h b/src/libs/cplusplus/LookupItem.h
index e2683c2877..bc760f8d8b 100644
--- a/src/libs/cplusplus/LookupItem.h
+++ b/src/libs/cplusplus/LookupItem.h
@@ -26,6 +26,7 @@
#pragma once
#include <cplusplus/FullySpecifiedType.h>
+#include <utils/porting.h>
#include <QHash>
@@ -70,6 +71,6 @@ private:
ClassOrNamespace *_binding;
};
-uint qHash(const CPlusPlus::LookupItem &result);
+Utils::QHashValueType qHash(const CPlusPlus::LookupItem &result);
} // namespace CPlusPlus
diff --git a/src/libs/extensionsystem/pluginspec.cpp b/src/libs/extensionsystem/pluginspec.cpp
index ea83933b7e..e3b2b07080 100644
--- a/src/libs/extensionsystem/pluginspec.cpp
+++ b/src/libs/extensionsystem/pluginspec.cpp
@@ -155,7 +155,7 @@ using namespace ExtensionSystem::Internal;
\fn uint ExtensionSystem::qHash(const ExtensionSystem::PluginDependency &value)
\internal
*/
-uint ExtensionSystem::qHash(const PluginDependency &value)
+Utils::QHashValueType ExtensionSystem::qHash(const PluginDependency &value)
{
return qHash(value.name);
}
diff --git a/src/libs/extensionsystem/pluginspec.h b/src/libs/extensionsystem/pluginspec.h
index d8d85ba520..4b2bcc1306 100644
--- a/src/libs/extensionsystem/pluginspec.h
+++ b/src/libs/extensionsystem/pluginspec.h
@@ -27,6 +27,8 @@
#include "extensionsystem_global.h"
+#include <utils/porting.h>
+
#include <QString>
#include <QHash>
#include <QVector>
@@ -65,7 +67,7 @@ struct EXTENSIONSYSTEM_EXPORT PluginDependency
QString toString() const;
};
-uint qHash(const ExtensionSystem::PluginDependency &value);
+Utils::QHashValueType qHash(const ExtensionSystem::PluginDependency &value);
struct EXTENSIONSYSTEM_EXPORT PluginArgumentDescription
{
diff --git a/src/libs/languageserverprotocol/jsonrpcmessages.cpp b/src/libs/languageserverprotocol/jsonrpcmessages.cpp
index 64045f1e3a..2b71d34a75 100644
--- a/src/libs/languageserverprotocol/jsonrpcmessages.cpp
+++ b/src/libs/languageserverprotocol/jsonrpcmessages.cpp
@@ -37,6 +37,7 @@
#include <QTextCodec>
namespace LanguageServerProtocol {
+Q_LOGGING_CATEGORY(timingLog, "qtc.languageserverprotocol.timing", QtWarningMsg)
constexpr const char CancelRequest::methodName[];
@@ -148,4 +149,10 @@ CancelRequest::CancelRequest(const CancelParameter &params)
: Notification(methodName, params)
{ }
+void logElapsedTime(const QString &method, const QElapsedTimer &t)
+{
+ qCDebug(timingLog) << "received server reply to" << method
+ << "after" << t.elapsed() << "ms";
+}
+
} // namespace LanguageServerProtocol
diff --git a/src/libs/languageserverprotocol/jsonrpcmessages.h b/src/libs/languageserverprotocol/jsonrpcmessages.h
index bb20ca8a3c..010bc770f8 100644
--- a/src/libs/languageserverprotocol/jsonrpcmessages.h
+++ b/src/libs/languageserverprotocol/jsonrpcmessages.h
@@ -34,6 +34,7 @@
#include <utils/variant.h>
#include <QDebug>
+#include <QElapsedTimer>
#include <QHash>
#include <QJsonObject>
#include <QJsonValue>
@@ -294,6 +295,8 @@ public:
{ return JsonRpcMessage::isValid(errorMessage) && id().isValid(); }
};
+void LANGUAGESERVERPROTOCOL_EXPORT logElapsedTime(const QString &method, const QElapsedTimer &t);
+
template <typename Result, typename ErrorDataType, typename Params>
class Request : public Notification<Params>
{
@@ -316,9 +319,13 @@ public:
Utils::optional<ResponseHandler> responseHandler() const final
{
- auto callback = [callback = m_callBack](const QByteArray &content, QTextCodec *codec) {
+ QElapsedTimer timer;
+ timer.start();
+ auto callback = [callback = m_callBack, method = this->method(), t = std::move(timer)]
+ (const QByteArray &content, QTextCodec *codec) {
if (!callback)
return;
+ logElapsedTime(method, t);
QString parseError;
const QJsonObject &object = JsonRpcMessageHandler::toJsonObject(content,
codec,
diff --git a/src/libs/languageserverprotocol/lsptypes.cpp b/src/libs/languageserverprotocol/lsptypes.cpp
index 820f4b6c4b..65651366a3 100644
--- a/src/libs/languageserverprotocol/lsptypes.cpp
+++ b/src/libs/languageserverprotocol/lsptypes.cpp
@@ -293,6 +293,14 @@ QTextCursor Position::toTextCursor(QTextDocument *doc) const
return cursor;
}
+Position Position::withOffset(int offset, const QTextDocument *doc) const
+{
+ int line;
+ int character;
+ Utils::Text::convertPosition(doc, toPositionInDocument(doc) + offset, &line, &character);
+ return Position(line - 1, character - 1);
+}
+
Range::Range(const Position &start, const Position &end)
{
setStart(start);
@@ -323,7 +331,7 @@ bool Range::contains(const Range &other) const
bool Range::overlaps(const Range &range) const
{
- return end() > range.start() && start() < range.end();
+ return !isLeftOf(range) && !range.isLeftOf(*this);
}
QString expressionForGlob(QString globPattern)
diff --git a/src/libs/languageserverprotocol/lsptypes.h b/src/libs/languageserverprotocol/lsptypes.h
index 7cbe045563..7bd004ca6c 100644
--- a/src/libs/languageserverprotocol/lsptypes.h
+++ b/src/libs/languageserverprotocol/lsptypes.h
@@ -90,6 +90,7 @@ public:
int toPositionInDocument(const QTextDocument *doc) const;
QTextCursor toTextCursor(QTextDocument *doc) const;
+ Position withOffset(int offset, const QTextDocument *doc) const;
};
inline bool operator<(const Position &first, const Position &second)
@@ -103,6 +104,11 @@ inline bool operator>(const Position &first, const Position &second)
return second < first;
}
+inline bool operator>=(const Position &first, const Position &second)
+{
+ return !(first < second);
+}
+
inline bool operator<=(const Position &first, const Position &second)
{
return !(first > second);
@@ -124,9 +130,12 @@ public:
Position end() const { return typedValue<Position>(endKey); }
void setEnd(const Position &end) { insert(endKey, end); }
+ bool isEmpty() const { return start() == end(); }
bool contains(const Position &pos) const { return start() <= pos && pos <= end(); }
bool contains(const Range &other) const;
bool overlaps(const Range &range) const;
+ bool isLeftOf(const Range &other) const
+ { return isEmpty() || other.isEmpty() ? end() < other.start() : end() <= other.start(); }
bool isValid() const override
{ return JsonObject::contains(startKey) && JsonObject::contains(endKey); }
diff --git a/src/libs/modelinglib/qmt/infrastructure/handle.h b/src/libs/modelinglib/qmt/infrastructure/handle.h
index b7333a1146..7558ec9699 100644
--- a/src/libs/modelinglib/qmt/infrastructure/handle.h
+++ b/src/libs/modelinglib/qmt/infrastructure/handle.h
@@ -74,7 +74,7 @@ private:
};
template<class T>
-inline int qHash(const Handle<T> &handle)
+inline auto qHash(const Handle<T> &handle)
{
return qHash(handle.uid());
}
diff --git a/src/libs/modelinglib/qmt/style/defaultstyleengine.cpp b/src/libs/modelinglib/qmt/style/defaultstyleengine.cpp
index f2da9a9292..47706f91fc 100644
--- a/src/libs/modelinglib/qmt/style/defaultstyleengine.cpp
+++ b/src/libs/modelinglib/qmt/style/defaultstyleengine.cpp
@@ -38,6 +38,7 @@
#include "qmt/infrastructure/qmtassert.h"
#include <utils/algorithm.h>
+#include <utils/porting.h>
#include <QSet>
@@ -82,7 +83,7 @@ public:
ObjectVisuals m_objectVisuals;
};
-uint qHash(const ObjectStyleKey &styleKey)
+Utils::QHashValueType qHash(const ObjectStyleKey &styleKey)
{
return ::qHash(styleKey.m_elementType) ^ qHash(styleKey.m_objectVisuals);
}
@@ -106,7 +107,7 @@ public:
DObject::VisualPrimaryRole m_visualPrimaryRole = DObject::PrimaryRoleNormal;
};
-uint qHash(const RelationStyleKey &styleKey)
+Utils::QHashValueType qHash(const RelationStyleKey &styleKey)
{
return ::qHash(styleKey.m_elementType) ^ ::qHash(styleKey.m_visualPrimaryRole);
}
@@ -127,7 +128,7 @@ public:
DAnnotation::VisualRole m_visualRole = DAnnotation::RoleNormal;
};
-uint qHash(const AnnotationStyleKey &styleKey)
+Utils::QHashValueType qHash(const AnnotationStyleKey &styleKey)
{
return ::qHash(styleKey.m_visualRole);
}
@@ -142,11 +143,11 @@ class BoundaryStyleKey
{
};
-uint qHash(const BoundaryStyleKey &styleKey)
+Utils::QHashValueType qHash(const BoundaryStyleKey &styleKey)
{
Q_UNUSED(styleKey)
- return 1;
+ return ::qHash(1);
}
bool operator==(const BoundaryStyleKey &lhs, const BoundaryStyleKey &rhs)
@@ -162,11 +163,11 @@ class SwimlaneStyleKey
{
};
-uint qHash(const SwimlaneStyleKey &styleKey)
+Utils::QHashValueType qHash(const SwimlaneStyleKey &styleKey)
{
Q_UNUSED(styleKey)
- return 1;
+ return ::qHash(1);
}
bool operator==(const SwimlaneStyleKey &lhs, const SwimlaneStyleKey &rhs)
diff --git a/src/libs/modelinglib/qmt/style/objectvisuals.cpp b/src/libs/modelinglib/qmt/style/objectvisuals.cpp
index a4bdadc26e..7db69f6965 100644
--- a/src/libs/modelinglib/qmt/style/objectvisuals.cpp
+++ b/src/libs/modelinglib/qmt/style/objectvisuals.cpp
@@ -82,7 +82,7 @@ bool operator==(const ObjectVisuals &lhs, const ObjectVisuals &rhs)
&& lhs.depth() == rhs.depth();
}
-uint qHash(const ObjectVisuals &objectVisuals)
+Utils::QHashValueType qHash(const ObjectVisuals &objectVisuals)
{
return ::qHash(static_cast<int>(objectVisuals.visualPrimaryRole()))
^ ::qHash(static_cast<int>(objectVisuals.visualSecondaryRole()))
diff --git a/src/libs/modelinglib/qmt/style/objectvisuals.h b/src/libs/modelinglib/qmt/style/objectvisuals.h
index 0d708fe0a5..dcc4bee623 100644
--- a/src/libs/modelinglib/qmt/style/objectvisuals.h
+++ b/src/libs/modelinglib/qmt/style/objectvisuals.h
@@ -27,6 +27,8 @@
#include "qmt/diagram/dobject.h"
+#include <utils/porting.h>
+
#include <QColor>
namespace qmt {
@@ -60,6 +62,6 @@ private:
};
bool operator==(const ObjectVisuals &lhs, const ObjectVisuals &rhs);
-uint qHash(const ObjectVisuals &objectVisuals);
+Utils::QHashValueType qHash(const ObjectVisuals &objectVisuals);
} // namespace qmt
diff --git a/src/libs/qlitehtml b/src/libs/qlitehtml
-Subproject 2fbaad08a01d611858bef5e747addea7f42318b
+Subproject e6fcc8ddb4e435160cca6a94bd7b011fd169865
diff --git a/src/libs/qmldebug/qpacketprotocol.cpp b/src/libs/qmldebug/qpacketprotocol.cpp
index 76822d34d4..24d4d29c54 100644
--- a/src/libs/qmldebug/qpacketprotocol.cpp
+++ b/src/libs/qmldebug/qpacketprotocol.cpp
@@ -225,7 +225,7 @@ void QPacketProtocol::send(const QByteArray &p)
return;
}
- const qint32 sendSize = p.size() + sizeof(qint32);
+ const qint32 sendSize = qint32(p.size() + sizeof(qint32));
d->sendingPackets.append(sendSize);
const qint32 sendSizeLE = qToLittleEndian(sendSize);
diff --git a/src/libs/qmljs/qmljscheck.cpp b/src/libs/qmljs/qmljscheck.cpp
index 3ce402589c..38595a8b36 100644
--- a/src/libs/qmljs/qmljscheck.cpp
+++ b/src/libs/qmljs/qmljscheck.cpp
@@ -1263,13 +1263,28 @@ static bool equalIsAlwaysFalse(const Value *lhs, const Value *rhs)
return false;
}
+static bool isIntegerValue(const Value *value)
+{
+ if (value->asNumberValue() || value->asIntValue())
+ return true;
+ if (auto obj = value->asObjectValue())
+ return obj->className() == "Number";
+
+ return false;
+}
+
static bool strictCompareConstant(const Value *lhs, const Value *rhs)
{
if (lhs->asUnknownValue() || rhs->asUnknownValue())
return false;
+ if (lhs->asFunctionValue() || rhs->asFunctionValue()) // function evaluation not implemented
+ return false;
+ if (isIntegerValue(lhs) && isIntegerValue(rhs))
+ return false;
if (lhs->asBooleanValue() && !rhs->asBooleanValue())
return true;
- if (lhs->asNumberValue() && !rhs->asNumberValue())
+ // attached properties and working at runtime cases may be undefined at evaluation time
+ if (lhs->asNumberValue() && (!rhs->asNumberValue() && !rhs->asUndefinedValue()))
return true;
if (lhs->asStringValue() && !rhs->asStringValue())
return true;
diff --git a/src/libs/qmljs/qmljsdialect.cpp b/src/libs/qmljs/qmljsdialect.cpp
index cfe71b2265..d0b922a720 100644
--- a/src/libs/qmljs/qmljsdialect.cpp
+++ b/src/libs/qmljs/qmljsdialect.cpp
@@ -221,9 +221,9 @@ QList<Dialect> Dialect::companionLanguages() const
return langs;
}
-uint qHash(const Dialect &o)
+Utils::QHashValueType qHash(const Dialect &o)
{
- return uint(o.dialect());
+ return Utils::QHashValueType(o.dialect());
}
QDebug operator << (QDebug &dbg, const Dialect &dialect)
diff --git a/src/libs/qmljs/qmljsdialect.h b/src/libs/qmljs/qmljsdialect.h
index a2f2822599..e594164278 100644
--- a/src/libs/qmljs/qmljsdialect.h
+++ b/src/libs/qmljs/qmljsdialect.h
@@ -28,6 +28,7 @@
#include "qmljs_global.h"
#include <utils/fileutils.h>
+#include <utils/porting.h>
#include <QDebug>
#include <QString>
@@ -73,7 +74,7 @@ private:
Enum m_dialect;
};
-QMLJS_EXPORT uint qHash(const Dialect &o);
+QMLJS_EXPORT Utils::QHashValueType qHash(const Dialect &o);
QMLJS_EXPORT QDebug operator << (QDebug &dbg, const Dialect &dialect);
diff --git a/src/libs/qmljs/qmljsimportdependencies.cpp b/src/libs/qmljs/qmljsimportdependencies.cpp
index 3cf94cb342..757ff2c388 100644
--- a/src/libs/qmljs/qmljsimportdependencies.cpp
+++ b/src/libs/qmljs/qmljsimportdependencies.cpp
@@ -502,9 +502,9 @@ QString ImportKey::toString() const
return res;
}
-uint qHash(const ImportKey &info)
+Utils::QHashValueType qHash(const ImportKey &info)
{
- uint res = ::qHash(info.type) ^
+ Utils::QHashValueType res = ::qHash(info.type) ^
::qHash(info.majorVersion) ^ ::qHash(info.minorVersion);
foreach (const QString &s, info.splitPath)
res = res ^ ::qHash(s);
diff --git a/src/libs/qmljs/qmljsimportdependencies.h b/src/libs/qmljs/qmljsimportdependencies.h
index 41f8491551..a05bf1b408 100644
--- a/src/libs/qmljs/qmljsimportdependencies.h
+++ b/src/libs/qmljs/qmljsimportdependencies.h
@@ -29,6 +29,7 @@
#include "qmljsdialect.h"
#include <languageutils/componentversion.h>
+#include <utils/porting.h>
#include <QObject>
#include <QString>
@@ -117,7 +118,7 @@ public:
QString toString() const;
};
-uint qHash(const ImportKey &info);
+Utils::QHashValueType qHash(const ImportKey &info);
bool operator ==(const ImportKey &i1, const ImportKey &i2);
bool operator !=(const ImportKey &i1, const ImportKey &i2);
bool operator <(const ImportKey &i1, const ImportKey &i2);
diff --git a/src/libs/qmljs/qmljsinterpreter.cpp b/src/libs/qmljs/qmljsinterpreter.cpp
index 9ae98e3530..47951eeb28 100644
--- a/src/libs/qmljs/qmljsinterpreter.cpp
+++ b/src/libs/qmljs/qmljsinterpreter.cpp
@@ -175,7 +175,7 @@ bool FakeMetaObjectWithOrigin::operator ==(const FakeMetaObjectWithOrigin &o) co
return fakeMetaObject == o.fakeMetaObject;
}
-uint qHash(const FakeMetaObjectWithOrigin &fmoo)
+Utils::QHashValueType qHash(const FakeMetaObjectWithOrigin &fmoo)
{
return qHash(fmoo.fakeMetaObject);
}
diff --git a/src/libs/qmljs/qmljsinterpreter.h b/src/libs/qmljs/qmljsinterpreter.h
index 6929386785..7322541e1a 100644
--- a/src/libs/qmljs/qmljsinterpreter.h
+++ b/src/libs/qmljs/qmljsinterpreter.h
@@ -31,6 +31,7 @@
#include <qmljs/parser/qmljsastfwd_p.h>
#include <languageutils/fakemetaobject.h>
+#include <utils/porting.h>
#include <QFileInfoList>
#include <QHash>
@@ -734,7 +735,7 @@ public:
bool operator ==(const FakeMetaObjectWithOrigin &o) const;
};
-QMLJS_EXPORT uint qHash(const FakeMetaObjectWithOrigin &fmoo);
+QMLJS_EXPORT Utils::QHashValueType qHash(const FakeMetaObjectWithOrigin &fmoo);
class QMLJS_EXPORT CppQmlTypes
{
diff --git a/src/libs/qmljs/qmljslink.cpp b/src/libs/qmljs/qmljslink.cpp
index 4fcdb0a748..58ead76afc 100644
--- a/src/libs/qmljs/qmljslink.cpp
+++ b/src/libs/qmljs/qmljslink.cpp
@@ -32,6 +32,7 @@
#include "qmljsmodelmanagerinterface.h"
#include "qmljsconstants.h"
+#include <utils/porting.h>
#include <utils/qrcparser.h>
#include <QDir>
@@ -54,7 +55,7 @@ public:
{}
private:
- friend uint qHash(const ImportCacheKey &);
+ friend Utils::QHashValueType qHash(const ImportCacheKey &);
friend bool operator==(const ImportCacheKey &, const ImportCacheKey &);
int m_type;
@@ -63,7 +64,7 @@ private:
int m_minorVersion;
};
-uint qHash(const ImportCacheKey &info)
+Utils::QHashValueType qHash(const ImportCacheKey &info)
{
return ::qHash(info.m_type) ^ ::qHash(info.m_path) ^
::qHash(info.m_majorVersion) ^ ::qHash(info.m_minorVersion);
diff --git a/src/libs/qmljs/qmljsmodelmanagerinterface.cpp b/src/libs/qmljs/qmljsmodelmanagerinterface.cpp
index 34048e8185..db08418ca7 100644
--- a/src/libs/qmljs/qmljsmodelmanagerinterface.cpp
+++ b/src/libs/qmljs/qmljsmodelmanagerinterface.cpp
@@ -1329,7 +1329,7 @@ bool rescanExports(const QString &fileName, FindExportedCppTypes &finder,
QList<LanguageUtils::FakeMetaObject::ConstPtr> exported = finder.exportedTypes();
QHash<QString, QString> contextProperties = finder.contextProperties();
if (exported.isEmpty() && contextProperties.isEmpty()) {
- hasNewInfo = hasNewInfo || newData.remove(fileName) > 0;
+ hasNewInfo = hasNewInfo || newData.remove(fileName);
} else {
ModelManagerInterface::CppData &data = newData[fileName];
if (!hasNewInfo && (data.exportedTypes.size() != exported.size()
@@ -1382,7 +1382,7 @@ void ModelManagerInterface::updateCppQmlTypes(
const bool scan = pair.second;
const QString fileName = doc->fileName();
if (!scan) {
- hasNewInfo = newData.remove(fileName) > 0 || hasNewInfo;
+ hasNewInfo = newData.remove(fileName) || hasNewInfo;
const auto savedDocs = newDeclarations.value(fileName);
for (const CPlusPlus::Document::Ptr &savedDoc : savedDocs) {
finder(savedDoc);
diff --git a/src/libs/tracing/CMakeLists.txt b/src/libs/tracing/CMakeLists.txt
index 9378c0e4e0..c34f583810 100644
--- a/src/libs/tracing/CMakeLists.txt
+++ b/src/libs/tracing/CMakeLists.txt
@@ -46,7 +46,7 @@ else() # < Qt 6.2
find_package(Qt6 COMPONENTS ShaderTools QUIET)
add_qtc_library(Tracing
- CONDITION TARGET Qt6::ShaderTools
+ CONDITION TARGET Qt6::ShaderTools AND TARGET Qt5::Quick
FEATURE_INFO
DEPENDS Utils Qt5::Qml Qt5::Quick
PUBLIC_DEPENDS Qt5::Widgets
diff --git a/src/libs/utils/CMakeLists.txt b/src/libs/utils/CMakeLists.txt
index 9db6ea5f1e..b94b2b4222 100644
--- a/src/libs/utils/CMakeLists.txt
+++ b/src/libs/utils/CMakeLists.txt
@@ -168,6 +168,7 @@ add_qtc_library(Utils
textfileformat.cpp textfileformat.h
textutils.cpp textutils.h
theme/theme.cpp theme/theme.h theme/theme_p.h
+ threadutils.cpp threadutils.h
tooltip/effects.h
tooltip/tips.cpp tooltip/tips.h
tooltip/tooltip.cpp tooltip/tooltip.h
diff --git a/src/libs/utils/elfreader.cpp b/src/libs/utils/elfreader.cpp
index 3ff3388041..1883585bc8 100644
--- a/src/libs/utils/elfreader.cpp
+++ b/src/libs/utils/elfreader.cpp
@@ -113,7 +113,7 @@ bool ElfMapper::map()
return fdlen > 0;
}
- file.setFileName(binary.fileName());
+ file.setFileName(binary.path());
if (!file.open(QIODevice::ReadOnly))
return false;
diff --git a/src/libs/utils/filepath.cpp b/src/libs/utils/filepath.cpp
index fd68683ace..065f96809e 100644
--- a/src/libs/utils/filepath.cpp
+++ b/src/libs/utils/filepath.cpp
@@ -819,6 +819,24 @@ FilePath FilePath::symLinkTarget() const
return FilePath::fromString(info.symLinkTarget());
}
+FilePath FilePath::mapToGlobalPath() const
+{
+ if (needsDevice()) {
+ QTC_ASSERT(s_deviceHooks.mapToGlobalPath, return {});
+ return s_deviceHooks.mapToGlobalPath(*this);
+ }
+ return *this;
+}
+
+QString FilePath::mapToDevicePath() const
+{
+ if (needsDevice()) {
+ QTC_ASSERT(s_deviceHooks.mapToDevicePath, return {});
+ return s_deviceHooks.mapToDevicePath(*this);
+ }
+ return m_data;
+}
+
FilePath FilePath::withExecutableSuffix() const
{
FilePath res = *this;
@@ -1280,7 +1298,7 @@ FilePath FilePath::stringAppended(const QString &str) const
return fn;
}
-uint FilePath::hash(uint seed) const
+QHashValueType FilePath::hash(uint seed) const
{
if (Utils::HostOsInfo::fileNameCaseSensitivity() == Qt::CaseInsensitive)
return qHash(m_data.toUpper(), seed);
diff --git a/src/libs/utils/filepath.h b/src/libs/utils/filepath.h
index 409421eaf5..a83c0aa517 100644
--- a/src/libs/utils/filepath.h
+++ b/src/libs/utils/filepath.h
@@ -26,6 +26,7 @@
#pragma once
#include "utils_global.h"
+#include "porting.h"
#include "hostosinfo.h"
@@ -140,7 +141,7 @@ public:
void clear();
bool isEmpty() const;
- uint hash(uint seed) const;
+ QHashValueType hash(uint seed) const;
[[nodiscard]] FilePath resolvePath(const FilePath &tail) const;
[[nodiscard]] FilePath resolvePath(const QString &tail) const;
@@ -161,6 +162,9 @@ public:
QDir::Filters filters = QDir::NoFilter,
QDirIterator::IteratorFlags flags = QDirIterator::NoIteratorFlags) const;
+ [[nodiscard]] FilePath mapToGlobalPath() const;
+ [[nodiscard]] QString mapToDevicePath() const;
+
// makes sure that capitalization of directories is canonical
// on Windows and macOS. This is rarely needed.
[[nodiscard]] FilePath normalizedPathName() const;
@@ -198,6 +202,11 @@ private:
using FilePaths = QList<FilePath>;
+inline QHashValueType qHash(const Utils::FilePath &a, uint seed = 0)
+{
+ return a.hash(seed);
+}
+
} // namespace Utils
QT_BEGIN_NAMESPACE
@@ -205,3 +214,13 @@ QTCREATOR_UTILS_EXPORT QDebug operator<<(QDebug dbg, const Utils::FilePath &c);
QT_END_NAMESPACE
Q_DECLARE_METATYPE(Utils::FilePath)
+
+namespace std {
+template<>
+struct QTCREATOR_UTILS_EXPORT hash<Utils::FilePath>
+{
+ using argument_type = Utils::FilePath;
+ using result_type = size_t;
+ result_type operator()(const argument_type &fn) const;
+};
+} // namespace std
diff --git a/src/libs/utils/fileutils.h b/src/libs/utils/fileutils.h
index a92017f770..c87ca5d5dd 100644
--- a/src/libs/utils/fileutils.h
+++ b/src/libs/utils/fileutils.h
@@ -78,6 +78,8 @@ public:
std::function<bool(const FilePath &, const FilePath &)> renameFile;
std::function<FilePath(const FilePath &, const QList<FilePath> &)> searchInPath;
std::function<FilePath(const FilePath &)> symLinkTarget;
+ std::function<FilePath(const FilePath &)> mapToGlobalPath;
+ std::function<QString(const FilePath &)> mapToDevicePath;
std::function<QList<FilePath>(const FilePath &, const QStringList &,
QDir::Filters, QDir::SortFlags)> dirEntries;
std::function<QByteArray(const FilePath &, qint64, qint64)> fileContents;
@@ -314,16 +316,5 @@ private:
QTCREATOR_UTILS_EXPORT QTextStream &operator<<(QTextStream &s, const FilePath &fn);
-inline uint qHash(const Utils::FilePath &a, uint seed = 0) { return a.hash(seed); }
-
} // namespace Utils
-namespace std {
-template<> struct QTCREATOR_UTILS_EXPORT hash<Utils::FilePath>
-{
- using argument_type = Utils::FilePath;
- using result_type = size_t;
- result_type operator()(const argument_type &fn) const;
-};
-} // namespace std
-
diff --git a/src/libs/utils/id.cpp b/src/libs/utils/id.cpp
index 26430a2938..1349dd8488 100644
--- a/src/libs/utils/id.cpp
+++ b/src/libs/utils/id.cpp
@@ -84,7 +84,7 @@ static bool operator==(const StringHolder &sh1, const StringHolder &sh2)
}
-static uint qHash(const StringHolder &sh)
+static auto qHash(const StringHolder &sh)
{
return QT_PREPEND_NAMESPACE(qHash)(sh.h, 0);
}
diff --git a/src/libs/utils/id.h b/src/libs/utils/id.h
index e0af61099c..5c6440bd56 100644
--- a/src/libs/utils/id.h
+++ b/src/libs/utils/id.h
@@ -26,6 +26,7 @@
#pragma once
#include "utils_global.h"
+#include "porting.h"
#include <QList>
#include <QMetaType>
@@ -79,7 +80,7 @@ private:
quintptr m_id = 0;
};
-inline uint qHash(Id id) { return static_cast<uint>(id.uniqueIdentifier()); }
+inline QHashValueType qHash(Id id) { return static_cast<QHashValueType>(id.uniqueIdentifier()); }
} // namespace Utils
diff --git a/src/libs/utils/link.cpp b/src/libs/utils/link.cpp
index 884936a7bb..1df67837b1 100644
--- a/src/libs/utils/link.cpp
+++ b/src/libs/utils/link.cpp
@@ -63,7 +63,7 @@ Link Link::fromFilePath(const FilePath &filePath, bool canContainLineNumber, QSt
return Link{filePath.withNewPath(fileName.left(postfixPos)), lineColumn.line, lineColumn.column};
}
-uint qHash(const Link &l)
+QHashValueType qHash(const Link &l)
{
QString s = l.targetFilePath.toString();
return qHash(s.append(':').append(QString::number(l.targetLine)).append(':')
diff --git a/src/libs/utils/link.h b/src/libs/utils/link.h
index 34c2c5a5cf..6d9fbb8ac1 100644
--- a/src/libs/utils/link.h
+++ b/src/libs/utils/link.h
@@ -25,7 +25,8 @@
#pragma once
-#include <utils/fileutils.h>
+#include "fileutils.h"
+#include "porting.h"
#include <QString>
#include <qmetatype.h>
@@ -75,7 +76,7 @@ public:
int targetColumn;
};
-uint QTCREATOR_UTILS_EXPORT qHash(const Link &l);
+QTCREATOR_UTILS_EXPORT QHashValueType qHash(const Link &l);
using ProcessLinkCallback = std::function<void(const Link &)>;
diff --git a/src/libs/utils/mimetypes/mimeglobpattern.cpp b/src/libs/utils/mimetypes/mimeglobpattern.cpp
index 9ab335b862..ae0899dd0e 100644
--- a/src/libs/utils/mimetypes/mimeglobpattern.cpp
+++ b/src/libs/utils/mimetypes/mimeglobpattern.cpp
@@ -83,6 +83,39 @@ void MimeGlobMatchResult::addMatch(const QString &mimeType, int weight, const QS
}
}
+MimeGlobPattern::PatternType MimeGlobPattern::detectPatternType(const QString &pattern) const
+{
+ const int patternLength = pattern.length();
+ if (!patternLength)
+ return OtherPattern;
+
+ const bool starCount = pattern.count(QLatin1Char('*')) == 1;
+ const bool hasSquareBracket = pattern.indexOf(QLatin1Char('[')) != -1;
+ const bool hasQuestionMark = pattern.indexOf(QLatin1Char('?')) != -1;
+
+ if (!hasSquareBracket && !hasQuestionMark) {
+ if (starCount == 1) {
+ // Patterns like "*~", "*.extension"
+ if (pattern.at(0) == QLatin1Char('*'))
+ return SuffixPattern;
+ // Patterns like "README*" (well this is currently the only one like that...)
+ if (pattern.at(patternLength - 1) == QLatin1Char('*'))
+ return PrefixPattern;
+ }
+ // Names without any wildcards like "README"
+ if (starCount == 0)
+ return LiteralPattern;
+ }
+
+ if (pattern == QLatin1String("[0-9][0-9][0-9].vdr"))
+ return VdrPattern;
+
+ if (pattern == QLatin1String("*.anim[1-9j]"))
+ return AnimPattern;
+
+ return OtherPattern;
+}
+
/*!
\internal
\class MimeGlobPattern
@@ -92,55 +125,63 @@ void MimeGlobMatchResult::addMatch(const QString &mimeType, int weight, const QS
\sa MimeType, MimeDatabase, MimeMagicRuleMatcher, MimeMagicRule
*/
-bool MimeGlobPattern::matchFileName(const QString &inputFilename) const
+bool MimeGlobPattern::matchFileName(const QString &inputFileName) const
{
// "Applications MUST match globs case-insensitively, except when the case-sensitive
// attribute is set to true."
// The constructor takes care of putting case-insensitive patterns in lowercase.
- const QString filename = m_caseSensitivity == Qt::CaseInsensitive ? inputFilename.toLower() : inputFilename;
+ const QString fileName = m_caseSensitivity == Qt::CaseInsensitive
+ ? inputFileName.toLower() : inputFileName;
- const int pattern_len = m_pattern.length();
- if (!pattern_len)
+ const int patternLength = m_pattern.length();
+ if (!patternLength)
return false;
- const int len = filename.length();
+ const int fileNameLength = fileName.length();
- const int starCount = m_pattern.count(QLatin1Char('*'));
+ switch (m_patternType) {
+ case SuffixPattern: {
+ if (fileNameLength + 1 < patternLength)
+ return false;
- // Patterns like "*~", "*.extension"
- if (m_pattern[0] == QLatin1Char('*') && m_pattern.indexOf(QLatin1Char('[')) == -1 && starCount == 1)
- {
- if (len + 1 < pattern_len) return false;
-
- const QChar *c1 = m_pattern.unicode() + pattern_len - 1;
- const QChar *c2 = filename.unicode() + len - 1;
+ const QChar *c1 = m_pattern.unicode() + patternLength - 1;
+ const QChar *c2 = fileName.unicode() + fileNameLength - 1;
int cnt = 1;
- while (cnt < pattern_len && *c1-- == *c2--)
+ while (cnt < patternLength && *c1-- == *c2--)
++cnt;
- return cnt == pattern_len;
+ return cnt == patternLength;
}
-
- // Patterns like "README*" (well this is currently the only one like that...)
- if (starCount == 1 && m_pattern.at(pattern_len - 1) == QLatin1Char('*')) {
- if (len + 1 < pattern_len) return false;
- if (m_pattern.at(0) == QLatin1Char('*'))
- return filename.indexOf(QStringView(m_pattern).mid(1, pattern_len - 2)) != -1;
+ case PrefixPattern: {
+ if (fileNameLength + 1 < patternLength)
+ return false;
const QChar *c1 = m_pattern.unicode();
- const QChar *c2 = filename.unicode();
+ const QChar *c2 = fileName.unicode();
int cnt = 1;
- while (cnt < pattern_len && *c1++ == *c2++)
+ while (cnt < patternLength && *c1++ == *c2++)
++cnt;
- return cnt == pattern_len;
+ return cnt == patternLength;
}
-
- // Names without any wildcards like "README"
- if (m_pattern.indexOf(QLatin1Char('[')) == -1 && starCount == 0 && m_pattern.indexOf(QLatin1Char('?')))
- return (m_pattern == filename);
-
- // Other (quite rare) patterns, like "*.anim[1-9j]": use slow but correct method
- const QRegularExpression rx(QRegularExpression::anchoredPattern(
+ case LiteralPattern:
+ return (m_pattern == fileName);
+ case VdrPattern: // "[0-9][0-9][0-9].vdr" case
+ return fileNameLength == 7
+ && fileName.at(0).isDigit() && fileName.at(1).isDigit() && fileName.at(2).isDigit()
+ && QStringView{fileName}.mid(3, 4) == QLatin1String(".vdr");
+ case AnimPattern: { // "*.anim[1-9j]" case
+ if (fileNameLength < 6)
+ return false;
+ const QChar lastChar = fileName.at(fileNameLength - 1);
+ const bool lastCharOK = (lastChar.isDigit() && lastChar != QLatin1Char('0'))
+ || lastChar == QLatin1Char('j');
+ return lastCharOK && QStringView{fileName}.mid(fileNameLength - 6, 5) == QLatin1String(".anim");
+ }
+ case OtherPattern:
+ // Other fallback patterns: slow but correct method
+ const QRegularExpression rx(QRegularExpression::anchoredPattern(
QRegularExpression::wildcardToRegularExpression(m_pattern)));
- return rx.match(filename).hasMatch();
+ return rx.match(fileName).hasMatch();
+ }
+ return false;
}
static bool isFastPattern(const QString &pattern)
diff --git a/src/libs/utils/mimetypes/mimeglobpattern_p.h b/src/libs/utils/mimetypes/mimeglobpattern_p.h
index ecbfb02ce9..990a5b07d2 100644
--- a/src/libs/utils/mimetypes/mimeglobpattern_p.h
+++ b/src/libs/utils/mimetypes/mimeglobpattern_p.h
@@ -73,16 +73,27 @@ public:
static const unsigned DefaultWeight = 50;
static const unsigned MinWeight = 1;
- explicit MimeGlobPattern(const QString &thePattern, const QString &theMimeType, unsigned theWeight = DefaultWeight, Qt::CaseSensitivity s = Qt::CaseInsensitive) :
- m_pattern(thePattern), m_mimeType(theMimeType), m_weight(theWeight), m_caseSensitivity(s)
+ explicit MimeGlobPattern(const QString &thePattern, const QString &theMimeType,
+ unsigned theWeight = DefaultWeight,
+ Qt::CaseSensitivity s = Qt::CaseInsensitive) :
+ m_pattern(s == Qt::CaseInsensitive ? thePattern.toLower() : thePattern),
+ m_mimeType(theMimeType),
+ m_weight(theWeight),
+ m_caseSensitivity(s),
+ m_patternType(detectPatternType(m_pattern))
{
- if (s == Qt::CaseInsensitive) {
- m_pattern = m_pattern.toLower();
- }
}
- ~MimeGlobPattern() {}
- bool matchFileName(const QString &filename) const;
+ void swap(MimeGlobPattern &other) noexcept
+ {
+ qSwap(m_pattern, other.m_pattern);
+ qSwap(m_mimeType, other.m_mimeType);
+ qSwap(m_weight, other.m_weight);
+ qSwap(m_caseSensitivity, other.m_caseSensitivity);
+ qSwap(m_patternType, other.m_patternType);
+ }
+
+ bool matchFileName(const QString &inputFileName) const;
inline const QString &pattern() const { return m_pattern; }
inline unsigned weight() const { return m_weight; }
@@ -90,10 +101,21 @@ public:
inline bool isCaseSensitive() const { return m_caseSensitivity == Qt::CaseSensitive; }
private:
+ enum PatternType {
+ SuffixPattern,
+ PrefixPattern,
+ LiteralPattern,
+ VdrPattern, // special handling for "[0-9][0-9][0-9].vdr" pattern
+ AnimPattern, // special handling for "*.anim[1-9j]" pattern
+ OtherPattern
+ };
+ PatternType detectPatternType(const QString &pattern) const;
+
QString m_pattern;
QString m_mimeType;
int m_weight;
Qt::CaseSensitivity m_caseSensitivity;
+ PatternType m_patternType;
};
class MimeGlobPatternList : public QList<MimeGlobPattern>
diff --git a/src/libs/utils/outputformatter.cpp b/src/libs/utils/outputformatter.cpp
index 4efcae7646..cf6930cbe5 100644
--- a/src/libs/utils/outputformatter.cpp
+++ b/src/libs/utils/outputformatter.cpp
@@ -136,8 +136,10 @@ bool OutputLineParser::demoteErrorsToWarnings() const
FilePath OutputLineParser::absoluteFilePath(const FilePath &filePath) const
{
- if (filePath.isEmpty() || filePath.toFileInfo().isAbsolute())
+ if (filePath.isEmpty())
return filePath;
+ if (filePath.toFileInfo().isAbsolute())
+ return filePath.cleanPath();
FilePaths candidates;
for (const FilePath &dir : searchDirectories()) {
FilePath candidate = dir.pathAppended(filePath.toString());
diff --git a/src/libs/utils/set_algorithm.h b/src/libs/utils/set_algorithm.h
index 42a21f3f2d..97e33a047f 100644
--- a/src/libs/utils/set_algorithm.h
+++ b/src/libs/utils/set_algorithm.h
@@ -99,6 +99,24 @@ bool set_intersection_compare(
return false;
}
+template<class InputIt1, class InputIt2, class Callable, class Compare>
+void set_greedy_difference(
+ InputIt1 first1, InputIt1 last1, InputIt2 first2, InputIt2 last2, Callable call, Compare comp)
+{
+ while (first1 != last1 && first2 != last2) {
+ if (comp(*first1, *first2)) {
+ call(*first1++);
+ } else if (comp(*first2, *first1)) {
+ ++first2;
+ } else {
+ ++first1;
+ }
+ }
+
+ while (first1 != last1)
+ call(*first1++);
+}
+
template<typename InputIt1, typename InputIt2, typename BinaryPredicate, typename Callable, typename Value>
Value mismatch_collect(InputIt1 first1,
InputIt1 last1,
diff --git a/tests/unit/unittest/qmldom-test.cpp b/src/libs/utils/threadutils.cpp
index b7e8557f10..7d10199c4a 100644
--- a/tests/unit/unittest/qmldom-test.cpp
+++ b/src/libs/utils/threadutils.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2017 The Qt Company Ltd.
+** Copyright (C) 2021 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
@@ -23,29 +23,16 @@
**
****************************************************************************/
-#include "googletest.h"
+#include "threadutils.h"
-// cast of the top level items (DomEnvironments,...)
-#include <qmldom/qqmldomtop_p.h>
+#include <QCoreApplication>
+#include <QThread>
-// everything is in the QQmlJS::Dom namespace
-using namespace QQmlJS::Dom;
+namespace Utils {
-namespace {
-
-class QmlDom : public ::testing::Test
-{
-public:
-// static void SetUpTestCase();
-// static void TearDownTestCase();
-
-protected:
-};
-
-TEST_F(QmlDom, First)
+bool isMainThread()
{
- DomItem env = DomEnvironment::create({}, DomEnvironment::Option::SingleThreaded
- | DomEnvironment::Option::NoDependencies);
+ return QThread::currentThread() == qApp->thread();
}
-} // anonymous
+} // namespace Utils
diff --git a/src/libs/3rdparty/syntax-highlighting/src/lib/ksyntaxhighlighting_export.h b/src/libs/utils/threadutils.h
index a39adb5ed6..cc59658c27 100644
--- a/src/libs/3rdparty/syntax-highlighting/src/lib/ksyntaxhighlighting_export.h
+++ b/src/libs/utils/threadutils.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2018 The Qt Company Ltd.
+** Copyright (C) 2021 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
@@ -25,10 +25,11 @@
#pragma once
-#include <QtGlobal>
+#include "utils_global.h"
+
+namespace Utils {
+
+QTCREATOR_UTILS_EXPORT bool isMainThread();
+
+} // namespace Utils
-#if defined(KSYNTAXHIGHLIGHTING_LIBRARY)
-# define KSYNTAXHIGHLIGHTING_EXPORT Q_DECL_EXPORT
-#else
-# define KSYNTAXHIGHLIGHTING_EXPORT Q_DECL_IMPORT
-#endif
diff --git a/src/libs/utils/utils-lib.pri b/src/libs/utils/utils-lib.pri
index ddaae4bb69..a8280ba326 100644
--- a/src/libs/utils/utils-lib.pri
+++ b/src/libs/utils/utils-lib.pri
@@ -143,6 +143,7 @@ SOURCES += \
$$PWD/link.cpp \
$$PWD/linecolumn.cpp \
$$PWD/multitextcursor.cpp \
+ $$PWD/threadutils.cpp \
$$PWD/singleton.cpp
HEADERS += \
@@ -310,6 +311,7 @@ HEADERS += \
$$PWD/launchersocket.h \
$$PWD/qtcsettings.h \
$$PWD/multitextcursor.h \
+ $$PWD/threadutils.h \
$$PWD/singleton.h
FORMS += $$PWD/filewizardpage.ui \
diff --git a/src/libs/utils/utils.qbs b/src/libs/utils/utils.qbs
index 77f80dd81b..6d888f87ac 100644
--- a/src/libs/utils/utils.qbs
+++ b/src/libs/utils/utils.qbs
@@ -298,6 +298,8 @@ Project {
"textfileformat.h",
"textutils.cpp",
"textutils.h",
+ "threadutils.cpp",
+ "threadutils.h",
"treemodel.cpp",
"treemodel.h",
"treeviewcombobox.cpp",
diff --git a/src/plugins/android/androidconfigurations.cpp b/src/plugins/android/androidconfigurations.cpp
index c769a744d2..7bc1c6310d 100644
--- a/src/plugins/android/androidconfigurations.cpp
+++ b/src/plugins/android/androidconfigurations.cpp
@@ -418,6 +418,28 @@ QString AndroidConfig::apiLevelNameFor(const SdkPlatform *platform)
QString("android-%1").arg(platform->apiLevel()) : "";
}
+int AndroidConfig::platformNameToApiLevel(const QString &platformName)
+{
+ int apiLevel = -1;
+ static const QRegularExpression re("(android-)(?<apiLevel>[0-9A-Z]{1,})",
+ QRegularExpression::CaseInsensitiveOption);
+ QRegularExpressionMatch match = re.match(platformName);
+ if (match.hasMatch()) {
+ QString apiLevelStr = match.captured("apiLevel");
+ bool isUInt;
+ apiLevel = apiLevelStr.toUInt(&isUInt);
+ if (!isUInt) {
+ if (apiLevelStr == 'Q')
+ apiLevel = 29;
+ else if (apiLevelStr == 'R')
+ apiLevel = 30;
+ else if (apiLevelStr == 'S')
+ apiLevel = 31;
+ }
+ }
+ return apiLevel;
+}
+
bool AndroidConfig::isCmdlineSdkToolsInstalled() const
{
QString toolPath("cmdline-tools/latest/bin/sdkmanager");
@@ -563,15 +585,10 @@ FilePath AndroidConfig::keytoolPath() const
QVector<AndroidDeviceInfo> AndroidConfig::connectedDevices(QString *error) const
{
- return connectedDevices(adbToolPath(), error);
-}
-
-QVector<AndroidDeviceInfo> AndroidConfig::connectedDevices(const FilePath &adbToolPath, QString *error)
-{
QVector<AndroidDeviceInfo> devices;
QtcProcess adbProc;
adbProc.setTimeoutS(30);
- CommandLine cmd{adbToolPath, {"devices"}};
+ CommandLine cmd{adbToolPath(), {"devices"}};
adbProc.setCommand(cmd);
adbProc.runBlocking();
if (adbProc.result() != QtcProcess::FinishedWithSuccess) {
@@ -597,8 +614,8 @@ QVector<AndroidDeviceInfo> AndroidConfig::connectedDevices(const FilePath &adbTo
AndroidDeviceInfo dev;
dev.serialNumber = serialNo;
dev.type = serialNo.startsWith(QLatin1String("emulator")) ? AndroidDeviceInfo::Emulator : AndroidDeviceInfo::Hardware;
- dev.sdk = getSDKVersion(adbToolPath, dev.serialNumber);
- dev.cpuAbi = getAbis(adbToolPath, dev.serialNumber);
+ dev.sdk = getSDKVersion(dev.serialNumber);
+ dev.cpuAbi = getAbis(dev.serialNumber);
if (deviceType == QLatin1String("unauthorized"))
dev.state = AndroidDeviceInfo::UnAuthorizedState;
else if (deviceType == QLatin1String("offline"))
@@ -633,10 +650,11 @@ bool AndroidConfig::isConnected(const QString &serialNumber) const
return false;
}
-QString AndroidConfig::getDeviceProperty(const FilePath &adbToolPath, const QString &device, const QString &property)
+QString AndroidConfig::getDeviceProperty(const QString &device, const QString &property)
{
// workaround for '????????????' serial numbers
- CommandLine cmd(adbToolPath, AndroidDeviceInfo::adbSelector(device));
+ CommandLine cmd(AndroidConfigurations::currentConfig().adbToolPath(),
+ AndroidDeviceInfo::adbSelector(device));
cmd.addArgs({"shell", "getprop", property});
QtcProcess adbProc;
@@ -649,9 +667,9 @@ QString AndroidConfig::getDeviceProperty(const FilePath &adbToolPath, const QStr
return adbProc.allOutput();
}
-int AndroidConfig::getSDKVersion(const FilePath &adbToolPath, const QString &device)
+int AndroidConfig::getSDKVersion(const QString &device)
{
- QString tmp = getDeviceProperty(adbToolPath, device, "ro.build.version.sdk");
+ QString tmp = getDeviceProperty(device, "ro.build.version.sdk");
if (tmp.isEmpty())
return -1;
return tmp.trimmed().toInt();
@@ -690,15 +708,37 @@ QString AndroidConfig::getAvdName(const QString &serialnumber)
return QString::fromLatin1(name).trimmed();
}
+static SdkToolResult emulatorNameAdbCommand(const QString &serialNumber)
+{
+ QStringList args = AndroidDeviceInfo::adbSelector(serialNumber);
+ args.append({"emu", "avd", "name"});
+ return AndroidManager::runAdbCommand(args);
+}
+
+QString AndroidConfig::getRunningAvdsSerialNumber(const QString &name) const
+{
+ for (const AndroidDeviceInfo &dev : connectedDevices()) {
+ if (!dev.serialNumber.startsWith("emulator"))
+ continue;
+ SdkToolResult result = emulatorNameAdbCommand(dev.serialNumber);
+ const QString stdOut = result.stdOut();
+ if (stdOut.isEmpty())
+ continue; // Not an avd
+ const QStringList outputLines = stdOut.split('\n');
+ if (outputLines.size() > 1 && outputLines.first() == name)
+ return dev.serialNumber;
+ }
+
+ return {};
+}
+
QStringList AndroidConfig::getRunningAvdsFromDevices(const QVector<AndroidDeviceInfo> &devs)
{
QStringList runningDevs;
for (const AndroidDeviceInfo &dev : devs) {
if (!dev.serialNumber.startsWith("emulator"))
continue;
- QStringList args = AndroidDeviceInfo::adbSelector(dev.serialNumber);
- args.append({"emu", "avd", "name"});
- SdkToolResult result = AndroidManager::runAdbCommand(args);
+ SdkToolResult result = emulatorNameAdbCommand(dev.serialNumber);
const QString stdOut = result.stdOut();
if (stdOut.isEmpty())
continue; // Not an avd
@@ -742,7 +782,7 @@ QString AndroidConfig::getProductModel(const QString &device) const
if (m_serialNumberToDeviceName.contains(device))
return m_serialNumberToDeviceName.value(device);
- QString model = getDeviceProperty(adbToolPath(), device, "ro.product.model").trimmed();
+ QString model = getDeviceProperty(device, "ro.product.model").trimmed();
if (model.isEmpty())
return device;
@@ -751,15 +791,16 @@ QString AndroidConfig::getProductModel(const QString &device) const
return model;
}
-QStringList AndroidConfig::getAbis(const FilePath &adbToolPath, const QString &device)
+QStringList AndroidConfig::getAbis(const QString &device)
{
+ const FilePath adbTool = AndroidConfigurations::currentConfig().adbToolPath();
QStringList result;
// First try via ro.product.cpu.abilist
QStringList arguments = AndroidDeviceInfo::adbSelector(device);
arguments << "shell" << "getprop" << "ro.product.cpu.abilist";
QtcProcess adbProc;
adbProc.setTimeoutS(10);
- adbProc.setCommand({adbToolPath, arguments});
+ adbProc.setCommand({adbTool, arguments});
adbProc.runBlocking();
if (adbProc.result() != QtcProcess::FinishedWithSuccess)
return result;
@@ -782,7 +823,7 @@ QStringList AndroidConfig::getAbis(const FilePath &adbToolPath, const QString &d
QtcProcess abiProc;
abiProc.setTimeoutS(10);
- abiProc.setCommand({adbToolPath, arguments});
+ abiProc.setCommand({adbTool, arguments});
abiProc.runBlocking();
if (abiProc.result() != QtcProcess::FinishedWithSuccess)
return result;
diff --git a/src/plugins/android/androidconfigurations.h b/src/plugins/android/androidconfigurations.h
index 09f7ac85f1..2fc22ddbc2 100644
--- a/src/plugins/android/androidconfigurations.h
+++ b/src/plugins/android/androidconfigurations.h
@@ -91,6 +91,7 @@ public:
static QStringList apiLevelNamesFor(const SdkPlatformList &platforms);
static QString apiLevelNameFor(const SdkPlatform *platform);
+ static int platformNameToApiLevel(const QString &platformName);
Utils::FilePath sdkLocation() const;
void setSdkLocation(const Utils::FilePath &sdkLocation);
@@ -144,7 +145,6 @@ public:
Utils::FilePath keytoolPath() const;
QVector<AndroidDeviceInfo> connectedDevices(QString *error = nullptr) const;
- static QVector<AndroidDeviceInfo> connectedDevices(const Utils::FilePath &adbToolPath, QString *error = nullptr);
QString bestNdkPlatformMatch(int target, const QtSupport::BaseQtVersion *qtVersion) const;
@@ -171,16 +171,16 @@ public:
void setOpenSslLocation(const Utils::FilePath &openSslLocation);
static Utils::FilePath getJdkPath();
- static QStringList getAbis(const Utils::FilePath &adbToolPath, const QString &device);
+ static QStringList getAbis(const QString &device);
+ QString getRunningAvdsSerialNumber(const QString &name) const;
static QStringList getRunningAvdsFromDevices(const QVector<AndroidDeviceInfo> &devs);
private:
- static QString getDeviceProperty(const Utils::FilePath &adbToolPath,
- const QString &device, const QString &property);
+ static QString getDeviceProperty(const QString &device, const QString &property);
Utils::FilePath openJDKBinPath() const;
- static int getSDKVersion(const Utils::FilePath &adbToolPath, const QString &device);
+ static int getSDKVersion(const QString &device);
static QString getAvdName(const QString &serialnumber);
void parseDependenciesJson();
diff --git a/src/plugins/android/androiddeployqtstep.cpp b/src/plugins/android/androiddeployqtstep.cpp
index 8c50c7a52c..0910f483d6 100644
--- a/src/plugins/android/androiddeployqtstep.cpp
+++ b/src/plugins/android/androiddeployqtstep.cpp
@@ -88,10 +88,11 @@ AndroidDeployQtStep::AndroidDeployQtStep(BuildStepList *parent, Utils::Id id)
: BuildStep(parent, id)
{
setImmutable(true);
+ setUserExpanded(true);
m_uninstallPreviousPackage = addAspect<BoolAspect>();
m_uninstallPreviousPackage->setSettingsKey(UninstallPreviousPackageKey);
- m_uninstallPreviousPackage->setLabel(tr("Uninstall the existing app first"),
+ m_uninstallPreviousPackage->setLabel(tr("Uninstall the existing app before deployment"),
BoolAspect::LabelPlacement::AtCheckBox);
m_uninstallPreviousPackage->setValue(false);
diff --git a/src/plugins/android/androiddevice.cpp b/src/plugins/android/androiddevice.cpp
index bba148dda8..ea4ddbf8e1 100644
--- a/src/plugins/android/androiddevice.cpp
+++ b/src/plugins/android/androiddevice.cpp
@@ -151,7 +151,7 @@ AndroidDevice::AndroidDevice()
setOsType(Utils::OsTypeOtherUnix);
setDeviceState(DeviceConnected);
- addDeviceAction({tr("Refresh"), [](const IDevice::Ptr &device, QWidget *parent) {
+ addDeviceAction({tr("Refresh"), [](const IDevice::Ptr &, QWidget *) {
AndroidDeviceManager::instance()->updateDevicesListOnce();
}});
@@ -334,7 +334,11 @@ bool AndroidDevice::isValid() const
QString AndroidDevice::serialNumber() const
{
- return extraData(Constants::AndroidSerialNumber).toString();
+ const QString serialNumber = extraData(Constants::AndroidSerialNumber).toString();
+ if (machineType() == Hardware)
+ return serialNumber;
+
+ return AndroidConfigurations::currentConfig().getRunningAvdsSerialNumber(avdName());
}
QString AndroidDevice::avdName() const
@@ -614,8 +618,8 @@ AndroidDeviceManager *AndroidDeviceManager::instance()
AndroidDeviceManager::AndroidDeviceManager(QObject *parent)
: QObject(parent),
- m_androidConfig(AndroidConfigurations::currentConfig()),
- m_avdManager(m_androidConfig)
+ m_avdManager(m_androidConfig),
+ m_androidConfig(AndroidConfigurations::currentConfig())
{
connect(qApp, &QCoreApplication::aboutToQuit, this, [this]() {
m_devicesUpdaterTimer.stop();
diff --git a/src/plugins/android/androidqmlpreviewworker.cpp b/src/plugins/android/androidqmlpreviewworker.cpp
index 3c2adca572..bb95616eac 100644
--- a/src/plugins/android/androidqmlpreviewworker.cpp
+++ b/src/plugins/android/androidqmlpreviewworker.cpp
@@ -254,7 +254,7 @@ bool AndroidQmlPreviewWorker::ensureAvdIsRunning()
appendMessage(tr("Could not start AVD."), ErrorMessageFormat);
} else {
m_serialNumber = devInfoLocal.serialNumber;
- m_avdAbis = m_androidConfig.getAbis(m_androidConfig.adbToolPath(), m_serialNumber);
+ m_avdAbis = m_androidConfig.getAbis(m_serialNumber);
}
return !devInfoLocal.serialNumber.isEmpty();
} else {
@@ -262,7 +262,7 @@ bool AndroidQmlPreviewWorker::ensureAvdIsRunning()
}
return false;
}
- m_avdAbis = m_androidConfig.getAbis(m_androidConfig.adbToolPath(), m_serialNumber);
+ m_avdAbis = m_androidConfig.getAbis(m_serialNumber);
return true;
}
diff --git a/src/plugins/android/androidrunconfiguration.cpp b/src/plugins/android/androidrunconfiguration.cpp
index e1477c2615..b0b3c58f99 100644
--- a/src/plugins/android/androidrunconfiguration.cpp
+++ b/src/plugins/android/androidrunconfiguration.cpp
@@ -90,17 +90,10 @@ AndroidRunConfiguration::AndroidRunConfiguration(Target *target, Utils::Id id)
auto amStartArgsAspect = addAspect<StringAspect>();
amStartArgsAspect->setId(Constants::ANDROID_AM_START_ARGS);
amStartArgsAspect->setSettingsKey("Android.AmStartArgsKey");
- amStartArgsAspect->setLabelText(tr("Activity manager start options:"));
+ amStartArgsAspect->setLabelText(tr("Activity manager start arguments:"));
amStartArgsAspect->setDisplayStyle(StringAspect::LineEditDisplay);
amStartArgsAspect->setHistoryCompleter("Android.AmStartArgs.History");
- auto warning = addAspect<StringAspect>();
- warning->setDisplayStyle(StringAspect::LabelDisplay);
- warning->setLabelPixmap(Icons::WARNING.pixmap());
- warning->setValue(tr("If the \"am start\" options conflict, the application might not start.\n"
- "%1 uses: am start -n <package_name>/<Activity_name> [-D].")
- .arg(Core::Constants::IDE_DISPLAY_NAME));
-
auto preStartShellCmdAspect = addAspect<BaseStringListAspect>();
preStartShellCmdAspect->setDisplayStyle(StringAspect::TextEditDisplay);
preStartShellCmdAspect->setId(Constants::ANDROID_PRESTARTSHELLCMDLIST);
diff --git a/src/plugins/android/androidrunnerworker.cpp b/src/plugins/android/androidrunnerworker.cpp
index 83c512a46a..759eba59e4 100644
--- a/src/plugins/android/androidrunnerworker.cpp
+++ b/src/plugins/android/androidrunnerworker.cpp
@@ -552,7 +552,6 @@ void AndroidRunnerWorker::asyncStartHelper()
runAdb(entry.split(' ', Qt::SkipEmptyParts));
QStringList args({"shell", "am", "start"});
- args << m_amStartExtraArgs;
args << "-n" << m_intentName;
if (m_useCppDebugger) {
args << "-D";
@@ -636,6 +635,7 @@ void AndroidRunnerWorker::asyncStartHelper()
}
}
+ args << m_amStartExtraArgs;
if (!m_extraAppParams.isEmpty()) {
QStringList appArgs =
diff --git a/src/plugins/android/androidsdkmanager.cpp b/src/plugins/android/androidsdkmanager.cpp
index 943e371178..eaa6996014 100644
--- a/src/plugins/android/androidsdkmanager.cpp
+++ b/src/plugins/android/androidsdkmanager.cpp
@@ -69,28 +69,6 @@ Q_GLOBAL_STATIC_WITH_ARGS(QRegularExpression, assertionReg,
using namespace Utils;
using SdkCmdFutureInterface = QFutureInterface<AndroidSdkManager::OperationOutput>;
-int platformNameToApiLevel(const QString &platformName)
-{
- int apiLevel = -1;
- QRegularExpression re("(android-)(?<apiLevel>[0-9A-Z]{1,})",
- QRegularExpression::CaseInsensitiveOption);
- QRegularExpressionMatch match = re.match(platformName);
- if (match.hasMatch()) {
- QString apiLevelStr = match.captured("apiLevel");
- bool isUInt;
- apiLevel = apiLevelStr.toUInt(&isUInt);
- if (!isUInt) {
- if (apiLevelStr == 'Q')
- apiLevel = 29;
- else if (apiLevelStr == 'R')
- apiLevel = 30;
- else if (apiLevelStr == 'S')
- apiLevel = 31;
- }
- }
- return apiLevel;
-}
-
/*!
Parses the \a line for a [spaces]key[spaces]value[spaces] pattern and returns
\c true if \a key is found, false otherwise. Result is copied into \a value.
@@ -714,7 +692,7 @@ AndroidSdkPackage *SdkManagerOutputParser::parsePlatform(const QStringList &data
SdkPlatform *platform = nullptr;
GenericPackageData packageData;
if (parseAbstractData(packageData, data, 2, "Platform")) {
- int apiLevel = platformNameToApiLevel(packageData.headerParts.at(1));
+ const int apiLevel = AndroidConfig::platformNameToApiLevel(packageData.headerParts.at(1));
if (apiLevel == -1) {
qCDebug(sdkManagerLog) << "Platform: Cannot parse api level:"<< data;
return nullptr;
@@ -734,7 +712,7 @@ QPair<SystemImage *, int> SdkManagerOutputParser::parseSystemImage(const QString
QPair <SystemImage *, int> result(nullptr, -1);
GenericPackageData packageData;
if (parseAbstractData(packageData, data, 4, "System-image")) {
- int apiLevel = platformNameToApiLevel(packageData.headerParts.at(1));
+ const int apiLevel = AndroidConfig::platformNameToApiLevel(packageData.headerParts.at(1));
if (apiLevel == -1) {
qCDebug(sdkManagerLog) << "System-image: Cannot parse api level:"<< data;
return result;
diff --git a/src/plugins/android/androidsdkmanagerwidget.cpp b/src/plugins/android/androidsdkmanagerwidget.cpp
index c576571d32..0fe8b83d31 100644
--- a/src/plugins/android/androidsdkmanagerwidget.cpp
+++ b/src/plugins/android/androidsdkmanagerwidget.cpp
@@ -98,12 +98,10 @@ AndroidSdkManagerWidget::AndroidSdkManagerWidget(AndroidConfig &config,
auto proxyModel = new PackageFilterModel(m_sdkModel);
m_ui->packagesView->setModel(proxyModel);
+ m_ui->packagesView->header()->setSectionResizeMode(QHeaderView::ResizeToContents);
m_ui->packagesView->header()->setSectionResizeMode(AndroidSdkModel::packageNameColumn,
- QHeaderView::ResizeToContents);
- m_ui->packagesView->header()->setSectionResizeMode(AndroidSdkModel::apiLevelColumn,
- QHeaderView::ResizeToContents);
- m_ui->packagesView->header()->setSectionResizeMode(AndroidSdkModel::packageRevisionColumn,
- QHeaderView::ResizeToContents);
+ QHeaderView::Stretch);
+ m_ui->packagesView->header()->setStretchLastSection(false);
connect(m_ui->expandCheck, &QCheckBox::stateChanged, [this](int state) {
if (state == Qt::Checked)
m_ui->packagesView->expandAll();
@@ -133,7 +131,6 @@ AndroidSdkManagerWidget::AndroidSdkManagerWidget(AndroidConfig &config,
m_ui->searchField->setPlaceholderText("Filter");
connect(m_ui->searchField, &QLineEdit::textChanged, [this, proxyModel](const QString &text) {
- const bool isExpanded = m_ui->expandCheck->isChecked();
proxyModel->setAcceptedSearchPackage(text);
m_sdkModel->resetSelection();
// It is more convenient to expand the view with the results
@@ -513,7 +510,7 @@ bool PackageFilterModel::filterAcceptsRow(int sourceRow, const QModelIndex &sour
}
}
- return showTopLevel || (packageState(srcIndex) & m_packageState) && packageFound(srcIndex);
+ return showTopLevel || ((packageState(srcIndex) & m_packageState) && packageFound(srcIndex));
}
OptionsDialog::OptionsDialog(AndroidSdkManager *sdkManager, const QStringList &args,
diff --git a/src/plugins/android/androidsdkmodel.cpp b/src/plugins/android/androidsdkmodel.cpp
index 2f83e86156..2d0e7af83e 100644
--- a/src/plugins/android/androidsdkmodel.cpp
+++ b/src/plugins/android/androidsdkmodel.cpp
@@ -40,7 +40,7 @@ static Q_LOGGING_CATEGORY(androidSdkModelLog, "qtc.android.sdkmodel", QtWarningM
namespace Android {
namespace Internal {
-const int packageColCount = 4;
+const int packageColCount = 3;
AndroidSdkModel::AndroidSdkModel(const AndroidConfig &config, AndroidSdkManager *sdkManager,
QObject *parent)
@@ -74,9 +74,6 @@ QVariant AndroidSdkModel::headerData(int section, Qt::Orientation orientation, i
case apiLevelColumn:
data = tr("API");
break;
- case operationColumn:
- data = tr("Operation");
- break;
default:
break;
}
@@ -162,7 +159,6 @@ QVariant AndroidSdkModel::data(const QModelIndex &index, int role) const
if (!index.isValid())
return QVariant();
-
if (!index.parent().isValid()) {
// Top level tools
if (index.row() == 0) {
@@ -202,25 +198,29 @@ QVariant AndroidSdkModel::data(const QModelIndex &index, int role) const
return p->revision().toString();
case apiLevelColumn:
return apiLevelStr;
- case operationColumn:
- if (p->type() == AndroidSdkPackage::SdkToolsPackage &&
- p->state() == AndroidSdkPackage::Installed) {
- return tr("Update Only");
- } else {
- return p->state() == AndroidSdkPackage::Installed ? tr("Uninstall") : tr("Install");
- }
default:
break;
}
}
- if (role == Qt::DecorationRole && index.column() == packageNameColumn) {
- return p->state() == AndroidSdkPackage::Installed ? Utils::Icons::OK.icon() :
- Utils::Icons::EMPTY16.icon();
+ if (index.column() == packageNameColumn) {
+ if (role == Qt::CheckStateRole) {
+ if (p->state() == AndroidSdkPackage::Installed)
+ return m_changeState.contains(p) ? Qt::Unchecked : Qt::Checked;
+ else
+ return m_changeState.contains(p) ? Qt::Checked : Qt::Unchecked;
+ }
+
+ if (role == Qt::FontRole) {
+ QFont font;
+ if (m_changeState.contains(p))
+ font.setBold(true);
+ return font;
+ }
}
- if (role == Qt::CheckStateRole && index.column() == operationColumn )
- return m_changeState.contains(p) ? Qt::Checked : Qt::Unchecked;
+ if (role == Qt::TextAlignmentRole && index.column() == packageRevisionColumn)
+ return Qt::AlignRight;
if (role == Qt::ToolTipRole)
return QString("%1 - (%2)").arg(p->descriptionText()).arg(p->sdkStylePath());
@@ -245,14 +245,14 @@ QHash<int, QByteArray> AndroidSdkModel::roleNames() const
Qt::ItemFlags AndroidSdkModel::flags(const QModelIndex &index) const
{
Qt::ItemFlags f = QAbstractItemModel::flags(index);
- if (index.column() == operationColumn)
+ if (index.column() == packageNameColumn)
f |= Qt::ItemIsUserCheckable;
void *ip = index.internalPointer();
- if (ip && index.column() == operationColumn) {
+ if (ip && index.column() == packageNameColumn) {
auto package = static_cast<const AndroidSdkPackage *>(ip);
- if (package->state() == AndroidSdkPackage::Installed &&
- package->type() == AndroidSdkPackage::SdkToolsPackage) {
+ if (package->state() == AndroidSdkPackage::Installed
+ && package->type() == AndroidSdkPackage::SdkToolsPackage) {
f &= ~Qt::ItemIsEnabled;
}
}
@@ -264,11 +264,14 @@ bool AndroidSdkModel::setData(const QModelIndex &index, const QVariant &value, i
void *ip = index.internalPointer();
if (ip && role == Qt::CheckStateRole) {
auto package = static_cast<const AndroidSdkPackage *>(ip);
- if (value.toInt() == Qt::Checked) {
+ if (value.toInt() == Qt::Checked && package->state() != AndroidSdkPackage::Installed) {
m_changeState << package;
emit dataChanged(index, index, {Qt::CheckStateRole});
} else if (m_changeState.remove(package)) {
emit dataChanged(index, index, {Qt::CheckStateRole});
+ } else if (value.toInt() == Qt::Unchecked) {
+ m_changeState.insert(package);
+ emit dataChanged(index, index, {Qt::CheckStateRole});
}
return true;
}
diff --git a/src/plugins/android/androidsdkmodel.h b/src/plugins/android/androidsdkmodel.h
index af25edfbb8..4a8d363a13 100644
--- a/src/plugins/android/androidsdkmodel.h
+++ b/src/plugins/android/androidsdkmodel.h
@@ -42,8 +42,7 @@ public:
enum PackageColumn {
packageNameColumn = 0,
apiLevelColumn,
- packageRevisionColumn,
- operationColumn
+ packageRevisionColumn
};
enum ExtraRoles {
diff --git a/src/plugins/android/avdmanageroutputparser.cpp b/src/plugins/android/avdmanageroutputparser.cpp
index 0ca8a74e73..ac758f41c7 100644
--- a/src/plugins/android/avdmanageroutputparser.cpp
+++ b/src/plugins/android/avdmanageroutputparser.cpp
@@ -24,6 +24,7 @@
****************************************************************************/
#include "avdmanageroutputparser.h"
+#include "androidconfigurations.h"
#include <projectexplorer/projectexplorerconstants.h>
#include <utils/algorithm.h>
@@ -97,7 +98,7 @@ static Utils::optional<AndroidDeviceInfo> parseAvd(const QStringList &deviceInfo
QSettings avdInfo(avdInfoFile.toString(), QSettings::IniFormat);
value = avdInfo.value(avdInfoTargetKey).toString();
if (!value.isEmpty())
- avd.sdk = value.section('-', -1).toInt();
+ avd.sdk = AndroidConfig::platformNameToApiLevel(value);
else
qCDebug(avdOutputParserLog)
<< "Avd Parsing: Cannot find sdk API:" << avdInfoFile.toString();
diff --git a/src/plugins/clangcodemodel/clangcodemodelplugin.cpp b/src/plugins/clangcodemodel/clangcodemodelplugin.cpp
index a6ead8c3fe..3a13c4542d 100644
--- a/src/plugins/clangcodemodel/clangcodemodelplugin.cpp
+++ b/src/plugins/clangcodemodel/clangcodemodelplugin.cpp
@@ -82,7 +82,7 @@ void ClangCodeModelPlugin::generateCompilationDB()
QFuture<GenerateCompilationDbResult> task
= QtConcurrent::run(&Internal::generateCompilationDB, projectInfo,
- CompilationDbPurpose::Project,
+ projectInfo->buildRoot(), CompilationDbPurpose::Project,
warningsConfigForProject(target->project()),
optionsForProject(target->project()));
Core::ProgressManager::addTask(task, tr("Generating Compilation DB"), "generate compilation db");
diff --git a/src/plugins/clangcodemodel/clangcompletionassistprocessor.cpp b/src/plugins/clangcodemodel/clangcompletionassistprocessor.cpp
index af964f5be9..1d924f8b2d 100644
--- a/src/plugins/clangcodemodel/clangcompletionassistprocessor.cpp
+++ b/src/plugins/clangcodemodel/clangcompletionassistprocessor.cpp
@@ -36,6 +36,7 @@
#include <cppeditor/cppdoxygen.h>
#include <cppeditor/cppmodelmanager.h>
+#include <cppeditor/cpptoolsreuse.h>
#include <cppeditor/editordocumenthandle.h>
#include <texteditor/codeassist/assistproposalitem.h>
@@ -44,10 +45,7 @@
#include <texteditor/codeassist/ifunctionhintproposalmodel.h>
#include <texteditor/texteditorsettings.h>
-#include <cplusplus/BackwardsScanner.h>
-#include <cplusplus/ExpressionUnderCursor.h>
#include <cplusplus/Icons.h>
-#include <cplusplus/SimpleLexer.h>
#include <clangsupport/filecontainer.h>
@@ -431,37 +429,8 @@ bool ClangCompletionAssistProcessor::accepts() const
if (pos - startOfName >= TextEditorSettings::completionSettings().m_characterThreshold) {
const QChar firstCharacter = m_interface->characterAt(startOfName);
if (firstCharacter.isLetter() || firstCharacter == QLatin1Char('_')) {
- // Finally check that we're not inside a comment or string (code copied from startOfOperator)
- QTextCursor tc(m_interface->textDocument());
- tc.setPosition(pos);
-
- SimpleLexer tokenize;
- LanguageFeatures lf = tokenize.languageFeatures();
- lf.qtMocRunEnabled = true;
- lf.objCEnabled = true;
- tokenize.setLanguageFeatures(lf);
- tokenize.setSkipComments(false);
- const Tokens &tokens = tokenize(tc.block().text(), BackwardsScanner::previousBlockState(tc.block()));
- const int tokenIdx = SimpleLexer::tokenBefore(tokens, qMax(0, tc.positionInBlock() - 1));
- const Token tk = (tokenIdx == -1) ? Token() : tokens.at(tokenIdx);
-
- if (!tk.isComment() && !tk.isLiteral()) {
- return true;
- } else if (tk.isLiteral()
- && tokens.size() == 3
- && tokens.at(0).kind() == T_POUND
- && tokens.at(1).kind() == T_IDENTIFIER) {
- const QString &line = tc.block().text();
- const Token &idToken = tokens.at(1);
- QStringView identifier = Utils::midView(line,
- idToken.utf16charsBegin(),
- idToken.utf16chars());
- if (identifier == QLatin1String("include")
- || identifier == QLatin1String("include_next")
- || (m_interface->objcEnabled() && identifier == QLatin1String("import"))) {
- return true;
- }
- }
+ return !CppEditor::isInCommentOrString(m_interface.data(),
+ m_interface->languageFeatures());
}
}
}
diff --git a/src/plugins/clangcodemodel/clangdclient.cpp b/src/plugins/clangcodemodel/clangdclient.cpp
index 5b3e76bee8..2b6044f3ac 100644
--- a/src/plugins/clangcodemodel/clangdclient.cpp
+++ b/src/plugins/clangcodemodel/clangdclient.cpp
@@ -94,8 +94,22 @@ static Q_LOGGING_CATEGORY(clangdLogServer, "qtc.clangcodemodel.clangd.server", Q
static Q_LOGGING_CATEGORY(clangdLogAst, "qtc.clangcodemodel.clangd.ast", QtWarningMsg);
static Q_LOGGING_CATEGORY(clangdLogHighlight, "qtc.clangcodemodel.clangd.highlight", QtWarningMsg);
static Q_LOGGING_CATEGORY(clangdLogTiming, "qtc.clangcodemodel.clangd.timing", QtWarningMsg);
+static Q_LOGGING_CATEGORY(clangdLogCompletion, "qtc.clangcodemodel.clangd.completion",
+ QtWarningMsg);
static QString indexingToken() { return "backgroundIndexProgress"; }
+static QStringView subViewLen(const QString &s, qsizetype start, qsizetype length)
+{
+ if (start < 0 || length < 0 || start + length > s.length())
+ return {};
+ return QStringView(s).mid(start, length);
+}
+
+static QStringView subViewEnd(const QString &s, qsizetype start, qsizetype end)
+{
+ return subViewLen(s, start, end - start);
+}
+
class AstNode : public JsonObject
{
public:
@@ -277,6 +291,58 @@ public:
- openingQuoteOffset - 1);
}
+ enum class FileStatus { Ours, Foreign, Mixed, Unknown };
+ FileStatus fileStatus(const Utils::FilePath &thisFile) const
+ {
+ const Utils::optional<QString> arcanaString = arcana();
+ if (!arcanaString)
+ return FileStatus::Unknown;
+
+ // Example arcanas:
+ // "FunctionDecl 0x7fffb5d0dbd0 </tmp/test.cpp:1:1, line:5:1> line:1:6 func 'void ()'"
+ // "VarDecl 0x7fffb5d0dcf0 </tmp/test.cpp:2:5, /tmp/test.h:1:1> /tmp/test.cpp:2:10 b 'bool' cinit"
+ // The second one is for a particularly silly construction where the RHS of an
+ // initialization comes from an included header.
+ const int openPos = arcanaString->indexOf('<');
+ if (openPos == -1)
+ return FileStatus::Unknown;
+ const int closePos = arcanaString->indexOf('>', openPos + 1);
+ if (closePos == -1)
+ return FileStatus::Unknown;
+ bool hasOurs = false;
+ bool hasOther = false;
+ for (int startPos = openPos + 1; startPos < closePos;) {
+ int colon1Pos = arcanaString->indexOf(':', startPos);
+ if (colon1Pos == -1 || colon1Pos > closePos)
+ break;
+ if (Utils::HostOsInfo::isWindowsHost())
+ colon1Pos = arcanaString->indexOf(':', colon1Pos + 1);
+ if (colon1Pos == -1 || colon1Pos > closePos)
+ break;
+ const int colon2Pos = arcanaString->indexOf(':', colon1Pos + 2);
+ if (colon2Pos == -1 || colon2Pos > closePos)
+ break;
+ const int line = subViewEnd(*arcanaString, colon1Pos + 1, colon2Pos).toString().toInt(); // TODO: Drop toString() once we require >= Qt 5.15
+ if (line == 0)
+ break;
+ const QStringView fileOrLineString = subViewEnd(*arcanaString, startPos, colon1Pos);
+ if (fileOrLineString != QLatin1String("line")) {
+ if (Utils::FilePath::fromUserInput(fileOrLineString.toString()) == thisFile)
+ hasOurs = true;
+ else
+ hasOther = true;
+ }
+ const int commaPos = arcanaString->indexOf(',', colon2Pos + 2);
+ if (commaPos != -1)
+ startPos = commaPos + 2;
+ else
+ break;
+ }
+ if (hasOurs)
+ return hasOther ? FileStatus::Mixed : FileStatus::Ours;
+ return hasOther ? FileStatus::Foreign : FileStatus::Unknown;
+ }
+
// For debugging.
void print(int indent = 0) const
{
@@ -298,6 +364,7 @@ static QList<AstNode> getAstPath(const AstNode &root, const Range &range)
QList<AstNode> path;
QList<AstNode> queue{root};
bool isRoot = true;
+
while (!queue.isEmpty()) {
AstNode curNode = queue.takeFirst();
if (!isRoot && !curNode.hasRange())
@@ -309,13 +376,39 @@ static QList<AstNode> getAstPath(const AstNode &root, const Range &range)
const auto children = curNode.children();
if (!children)
break;
- queue = children.value();
+ if (curNode.kind() == "Function" || curNode.role() == "expression") {
+ // Functions and expressions can contain implicit nodes that make the list unsorted.
+ // They cannot be ignored, as we need to consider them in certain contexts.
+ // Therefore, the binary search cannot be used here.
+ queue = *children;
+ } else {
+ queue.clear();
+
+ // Class and struct nodes can contain implicit constructors, destructors and
+ // operators, which appear at the end of the list, but whose range is the same
+ // as the class name. Therefore, we must force them not to compare less to
+ // anything else.
+ static const auto leftOfRange = [](const AstNode &node, const Range &range) {
+ return node.range().isLeftOf(range) && !node.arcanaContains(" implicit ");
+ };
+
+ for (auto it = std::lower_bound(children->cbegin(), children->cend(), range,
+ leftOfRange);
+ it != children->cend() && !range.isLeftOf(it->range()); ++it) {
+ queue << *it;
+ }
+ }
}
isRoot = false;
}
return path;
}
+static QList<AstNode> getAstPath(const AstNode &root, const Position &pos)
+{
+ return getAstPath(root, Range(pos, pos));
+}
+
static Usage::Type getUsageType(const QList<AstNode> &path)
{
bool potentialWrite = false;
@@ -685,20 +778,12 @@ private:
case CustomAssistMode::Preprocessor:
static QIcon macroIcon = Utils::CodeModelIcon::iconForType(Utils::CodeModelIcon::Macro);
for (const QString &completion
- : CppEditor::CppCompletionAssistProcessor::preprocessorCompletions())
+ : CppEditor::CppCompletionAssistProcessor::preprocessorCompletions()) {
completions << createItem(completion, macroIcon);
- const CppEditor::ProjectFile::Kind fileType
- = CppEditor::ProjectFile::classify(interface->filePath().toString());
- switch (fileType) {
- case CppEditor::ProjectFile::ObjCHeader:
- case CppEditor::ProjectFile::ObjCXXHeader:
- case CppEditor::ProjectFile::ObjCSource:
- case CppEditor::ProjectFile::ObjCXXSource:
- completions << createItem("import", macroIcon);
- break;
- default:
- break;
}
+ if (CppEditor::ProjectFile::isObjC(interface->filePath().toString()))
+ completions << createItem("import", macroIcon);
+ break;
}
GenericProposalModelPtr model(new GenericProposalModel);
model->loadContent(completions);
@@ -1030,12 +1115,14 @@ public:
ClangdCompletionAssistProvider(ClangdClient *client);
private:
- IAssistProcessor *createProcessor(const AssistInterface *assistInterface) const override;
+ IAssistProcessor *createProcessor(const AssistInterface *interface) const override;
int activationCharSequenceLength() const override { return 3; }
bool isActivationCharSequence(const QString &sequence) const override;
bool isContinuationChar(const QChar &c) const override;
+ bool isInCommentOrString(const AssistInterface *interface) const;
+
ClangdClient * const m_client;
};
@@ -1048,6 +1135,7 @@ ClangdClient::ClangdClient(Project *project, const Utils::FilePath &jsonDbDir)
"text/x-c++hdr", "text/x-c++src", "text/x-objc++src", "text/x-objcsrc"};
setSupportedLanguage(langFilter);
setActivateDocumentAutomatically(true);
+ setLogTarget(LogTarget::Console);
setCompletionAssistProvider(new ClangdCompletionAssistProvider(this));
if (!project) {
QJsonObject initOptions;
@@ -1643,7 +1731,7 @@ void ClangdClient::findLocalUsages(TextDocument *document, const QTextCursor &cu
}
const Position linkPos(link.targetLine - 1, link.targetColumn);
- const QList<AstNode> astPath = getAstPath(ast, Range(linkPos, linkPos));
+ const QList<AstNode> astPath = getAstPath(ast, linkPos);
bool isVar = false;
for (auto it = astPath.rbegin(); it != astPath.rend(); ++it) {
if (it->role() == "declaration" && it->kind() == "Function") {
@@ -2128,7 +2216,8 @@ class ExtraHighlightingResultsCollector
{
public:
ExtraHighlightingResultsCollector(QFutureInterface<HighlightingResult> &future,
- HighlightingResults &results, const AstNode &ast,
+ HighlightingResults &results,
+ const Utils::FilePath &filePath, const AstNode &ast,
const QTextDocument *doc, const QString &docContent);
void collect();
@@ -2145,6 +2234,7 @@ private:
QFutureInterface<HighlightingResult> &m_future;
HighlightingResults &m_results;
+ const Utils::FilePath m_filePath;
const AstNode &m_ast;
const QTextDocument * const m_doc;
const QString &m_docContent;
@@ -2174,7 +2264,7 @@ static QList<BlockRange> cleanupDisabledCode(HighlightingResults &results, const
if (!wasIfdefedOut)
rangeStartPos = doc->findBlockByNumber(it->line - 1).position();
const int pos = Utils::Text::positionInText(doc, it->line, it->column);
- const QStringView content(QStringView(docContent).mid(pos, it->length).trimmed());
+ const QStringView content = subViewLen(docContent, pos, it->length).trimmed();
if (!content.startsWith(QLatin1String("#if"))
&& !content.startsWith(QLatin1String("#elif"))
&& !content.startsWith(QLatin1String("#else"))
@@ -2210,6 +2300,7 @@ static QList<BlockRange> cleanupDisabledCode(HighlightingResults &results, const
}
static void semanticHighlighter(QFutureInterface<HighlightingResult> &future,
+ const Utils::FilePath &filePath,
const QList<ExpandedSemanticToken> &tokens,
const QString &docContents, const AstNode &ast,
const QPointer<TextEditorWidget> &widget,
@@ -2222,13 +2313,17 @@ static void semanticHighlighter(QFutureInterface<HighlightingResult> &future,
}
const QTextDocument doc(docContents);
- const auto isOutputParameter = [&ast](const ExpandedSemanticToken &token) {
+ const auto tokenRange = [&doc](const ExpandedSemanticToken &token) {
+ const Position startPos(token.line - 1, token.column - 1);
+ const Position endPos = startPos.withOffset(token.length, &doc);
+ return Range(startPos, endPos);
+ };
+ const auto isOutputParameter = [&ast, &doc, &tokenRange](const ExpandedSemanticToken &token) {
if (token.modifiers.contains("usedAsMutableReference"))
return true;
if (token.type != "variable" && token.type != "property" && token.type != "parameter")
return false;
- const Position pos(token.line - 1, token.column - 1);
- const QList<AstNode> path = getAstPath(ast, Range(pos, pos));
+ const QList<AstNode> path = getAstPath(ast, tokenRange(token));
if (path.size() < 2)
return false;
if (path.last().hasConstType())
@@ -2249,7 +2344,8 @@ static void semanticHighlighter(QFutureInterface<HighlightingResult> &future,
};
const std::function<HighlightingResult(const ExpandedSemanticToken &)> toResult
- = [&ast, &isOutputParameter, &clangdVersion](const ExpandedSemanticToken &token) {
+ = [&ast, &isOutputParameter, &clangdVersion, &tokenRange]
+ (const ExpandedSemanticToken &token) {
TextStyles styles;
if (token.type == "variable") {
if (token.modifiers.contains("functionScope")) {
@@ -2263,8 +2359,7 @@ static void semanticHighlighter(QFutureInterface<HighlightingResult> &future,
} else if (token.type == "function" || token.type == "method") {
styles.mainStyle = token.modifiers.contains("virtual") ? C_VIRTUAL_METHOD : C_FUNCTION;
if (ast.isValid()) {
- const Position pos(token.line - 1, token.column - 1);
- const QList<AstNode> path = getAstPath(ast, Range(pos, pos));
+ const QList<AstNode> path = getAstPath(ast, tokenRange(token));
if (path.length() > 1) {
const AstNode declNode = path.at(path.length() - 2);
if (declNode.kind() == "Function" || declNode.kind() == "CXXMethod") {
@@ -2283,8 +2378,7 @@ static void semanticHighlighter(QFutureInterface<HighlightingResult> &future,
// clang hardly ever differentiates between constructors and the associated class,
// whereas we highlight constructors as functions.
if (ast.isValid()) {
- const Position pos(token.line - 1, token.column - 1);
- const QList<AstNode> path = getAstPath(ast, Range(pos, pos));
+ const QList<AstNode> path = getAstPath(ast, tokenRange(token));
if (!path.isEmpty()) {
if (path.last().kind() == "CXXConstructor") {
if (!path.last().arcanaContains("implicit"))
@@ -2338,7 +2432,7 @@ static void semanticHighlighter(QFutureInterface<HighlightingResult> &future,
if (widget && widget->textDocument()->document()->revision() == docRevision)
widget->setIfdefedOutBlocks(ifdefedOutBlocks);
}, Qt::QueuedConnection);
- ExtraHighlightingResultsCollector(future, results, ast, &doc, docContents).collect();
+ ExtraHighlightingResultsCollector(future, results, filePath, ast, &doc, docContents).collect();
if (!future.isCanceled()) {
qCDebug(clangdLog) << "reporting" << results.size() << "highlighting results";
future.reportResults(QVector<HighlightingResult>(results.cbegin(),
@@ -2378,10 +2472,12 @@ void ClangdClient::Private::handleSemanticTokens(TextDocument *doc,
IEditor * const editor = Utils::findOrDefault(EditorManager::visibleEditors(),
[doc](const IEditor *editor) { return editor->document() == doc; });
const auto editorWidget = TextEditorWidget::fromEditor(editor);
- const auto runner = [tokens, text = doc->document()->toPlainText(), ast,
+ const auto runner = [tokens, filePath = doc->filePath(),
+ text = doc->document()->toPlainText(), ast,
w = QPointer(editorWidget), rev = doc->document()->revision(),
clangdVersion = q->versionNumber()] {
- return Utils::runAsync(semanticHighlighter, tokens, text, ast, w, rev, clangdVersion);
+ return Utils::runAsync(semanticHighlighter, filePath, tokens, text, ast, w, rev,
+ clangdVersion);
};
if (isTesting) {
@@ -2543,21 +2639,28 @@ ClangdClient::ClangdCompletionAssistProvider::ClangdCompletionAssistProvider(Cla
{}
IAssistProcessor *ClangdClient::ClangdCompletionAssistProvider::createProcessor(
- const AssistInterface *assistInterface) const
-{
- ClangCompletionContextAnalyzer contextAnalyzer(assistInterface->textDocument(),
- assistInterface->position(), false, {});
+ const AssistInterface *interface) const
+{
+ qCDebug(clangdLogCompletion) << "completion processor requested for" << interface->filePath();
+ qCDebug(clangdLogCompletion) << "text before cursor is"
+ << interface->textAt(interface->position(), -10);
+ qCDebug(clangdLogCompletion) << "text after cursor is"
+ << interface->textAt(interface->position(), 10);
+ ClangCompletionContextAnalyzer contextAnalyzer(interface->textDocument(),
+ interface->position(), false, {});
contextAnalyzer.analyze();
switch (contextAnalyzer.completionAction()) {
case ClangCompletionContextAnalyzer::PassThroughToLibClangAfterLeftParen:
- qCDebug(clangdLog) << "completion changed to function hint";
+ qCDebug(clangdLogCompletion) << "creating function hint processor";
return new ClangdFunctionHintProcessor(m_client);
case ClangCompletionContextAnalyzer::CompleteDoxygenKeyword:
+ qCDebug(clangdLogCompletion) << "creating doxygen processor";
return new CustomAssistProcessor(m_client,
contextAnalyzer.positionForProposal(),
contextAnalyzer.completionOperator(),
CustomAssistMode::Doxygen);
case ClangCompletionContextAnalyzer::CompletePreprocessorDirective:
+ qCDebug(clangdLogCompletion) << "creating macro processor";
return new CustomAssistProcessor(m_client,
contextAnalyzer.positionForProposal(),
contextAnalyzer.completionOperator(),
@@ -2565,9 +2668,11 @@ IAssistProcessor *ClangdClient::ClangdCompletionAssistProvider::createProcessor(
default:
break;
}
- const QString snippetsGroup = contextAnalyzer.addSnippets()
+ const QString snippetsGroup = contextAnalyzer.addSnippets() && !isInCommentOrString(interface)
? CppEditor::Constants::CPP_SNIPPETS_GROUP_ID
: QString();
+ qCDebug(clangdLogCompletion) << "creating proper completion processor"
+ << (snippetsGroup.isEmpty() ? "without" : "with") << "snippets";
return new ClangdCompletionAssistProcessor(m_client, snippetsGroup);
}
@@ -2588,6 +2693,7 @@ bool ClangdClient::ClangdCompletionAssistProvider::isActivationCharSequence(cons
// contexts, such as '(', '<' or '/'.
switch (kind) {
case T_DOT: case T_COLON_COLON: case T_ARROW: case T_DOT_STAR: case T_ARROW_STAR: case T_POUND:
+ qCDebug(clangdLogCompletion) << "detected" << sequence << "as activation char sequence";
return true;
}
return false;
@@ -2598,6 +2704,14 @@ bool ClangdClient::ClangdCompletionAssistProvider::isContinuationChar(const QCha
return CppEditor::isValidIdentifierChar(c);
}
+bool ClangdClient::ClangdCompletionAssistProvider::isInCommentOrString(
+ const AssistInterface *interface) const
+{
+ LanguageFeatures features = LanguageFeatures::defaultFeatures();
+ features.objCEnabled = CppEditor::ProjectFile::isObjC(interface->filePath().toString());
+ return CppEditor::isInCommentOrString(interface, features);
+}
+
void ClangdCompletionItem::apply(TextDocumentManipulatorInterface &manipulator,
int /*basePosition*/) const
{
@@ -2607,35 +2721,27 @@ void ClangdCompletionItem::apply(TextDocumentManipulatorInterface &manipulator,
if (!edit)
return;
- const auto kind = static_cast<CompletionItemKind::Kind>(
- item.kind().value_or(CompletionItemKind::Text));
- if (kind != CompletionItemKind::Function && kind != CompletionItemKind::Method
- && kind != CompletionItemKind::Constructor) {
- applyTextEdit(manipulator, *edit, true);
- return;
- }
-
const QString rawInsertText = edit->newText();
const int firstParenOffset = rawInsertText.indexOf('(');
const int lastParenOffset = rawInsertText.lastIndexOf(')');
- if (firstParenOffset == -1 || lastParenOffset == -1) {
- applyTextEdit(manipulator, *edit, true);
- return;
- }
-
const QString detail = item.detail().value_or(QString());
const CompletionSettings &completionSettings = TextEditorSettings::completionSettings();
QString textToBeInserted = rawInsertText.left(firstParenOffset);
QString extraCharacters;
+ int extraLength = 0;
int cursorOffset = 0;
bool setAutoCompleteSkipPos = false;
- const QTextDocument * const doc = manipulator.textCursorAt(
- manipulator.currentPosition()).document();
+ int currentPos = manipulator.currentPosition();
+ const QTextDocument * const doc = manipulator.textCursorAt(currentPos).document();
const Range range = edit->range();
const int rangeStart = range.start().toPositionInDocument(doc);
- const int rangeLength = range.end().toPositionInDocument(doc) - rangeStart;
- if (completionSettings.m_autoInsertBrackets) {
+ const auto kind = static_cast<CompletionItemKind::Kind>(
+ item.kind().value_or(CompletionItemKind::Text));
+ const bool isFunctionLike = kind == CompletionItemKind::Function
+ || kind == CompletionItemKind::Method || kind == CompletionItemKind::Constructor
+ || (firstParenOffset != -1 && lastParenOffset != -1);
+ if (isFunctionLike && completionSettings.m_autoInsertBrackets) {
// If the user typed the opening parenthesis, they'll likely also type the closing one,
// in which case it would be annoying if we put the cursor after the already automatically
// inserted closing parenthesis.
@@ -2663,7 +2769,7 @@ void ClangdCompletionItem::apply(TextDocumentManipulatorInterface &manipulator,
// If the function doesn't return anything, automatically place the semicolon,
// unless we're doing a scope completion (then it might be function definition).
- const QChar characterAtCursor = manipulator.characterAt(manipulator.currentPosition());
+ const QChar characterAtCursor = manipulator.characterAt(currentPos);
bool endWithSemicolon = typedChar == ';';
const QChar semicolon = typedChar.isNull() ? QLatin1Char(';') : typedChar;
if (endWithSemicolon && characterAtCursor == semicolon) {
@@ -2679,7 +2785,7 @@ void ClangdCompletionItem::apply(TextDocumentManipulatorInterface &manipulator,
typedChar = {};
}
} else {
- const QChar lookAhead = manipulator.characterAt(manipulator.currentPosition() + 1);
+ const QChar lookAhead = manipulator.characterAt(currentPos + 1);
if (MatchingText::shouldInsertMatchingText(lookAhead)) {
extraCharacters += ')';
--cursorOffset;
@@ -2701,9 +2807,26 @@ void ClangdCompletionItem::apply(TextDocumentManipulatorInterface &manipulator,
--cursorOffset;
}
- textToBeInserted += extraCharacters;
+ // Avoid inserting characters that are already there
+ QTextCursor cursor = manipulator.textCursorAt(rangeStart);
+ cursor.movePosition(QTextCursor::EndOfWord);
+ const QString textAfterCursor = manipulator.textAt(currentPos, cursor.position() - currentPos);
+ if (textToBeInserted != textAfterCursor
+ && textToBeInserted.indexOf(textAfterCursor, currentPos - rangeStart) >= 0) {
+ currentPos = cursor.position();
+ }
+ for (int i = 0; i < extraCharacters.length(); ++i) {
+ const QChar a = extraCharacters.at(i);
+ const QChar b = manipulator.characterAt(currentPos + i);
+ if (a == b)
+ ++extraLength;
+ else
+ break;
+ }
- const bool isReplaced = manipulator.replace(rangeStart, rangeLength, textToBeInserted);
+ textToBeInserted += extraCharacters;
+ const int length = currentPos - rangeStart + extraLength;
+ const bool isReplaced = manipulator.replace(rangeStart, length, textToBeInserted);
manipulator.setCursorPosition(rangeStart + textToBeInserted.length());
if (isReplaced) {
if (cursorOffset)
@@ -2806,10 +2929,11 @@ MessageId ClangdClient::Private::getAndHandleAst(const TextDocOrFile &doc,
ExtraHighlightingResultsCollector::ExtraHighlightingResultsCollector(
QFutureInterface<HighlightingResult> &future, HighlightingResults &results,
- const AstNode &ast, const QTextDocument *doc, const QString &docContent)
- : m_future(future), m_results(results), m_ast(ast), m_doc(doc), m_docContent(docContent)
+ const Utils::FilePath &filePath, const AstNode &ast, const QTextDocument *doc,
+ const QString &docContent)
+ : m_future(future), m_results(results), m_filePath(filePath), m_ast(ast), m_doc(doc),
+ m_docContent(docContent)
{
-
}
void ExtraHighlightingResultsCollector::collect()
@@ -2881,7 +3005,7 @@ void ExtraHighlightingResultsCollector::insertAngleBracketInfo(int searchStart1,
int searchStart2, int searchEnd2)
{
const int openingAngleBracketPos = onlyIndexOf(
- QStringView(m_docContent).mid(searchStart1, searchEnd1 - searchStart1),
+ subViewEnd(m_docContent, searchStart1, searchEnd1),
QStringView(QStringLiteral("<")));
if (openingAngleBracketPos == -1)
return;
@@ -2891,7 +3015,7 @@ void ExtraHighlightingResultsCollector::insertAngleBracketInfo(int searchStart1,
if (searchStart2 >= searchEnd2)
return;
const int closingAngleBracketPos = onlyIndexOf(
- QStringView(m_docContent).mid(searchStart2, searchEnd2 - searchStart2),
+ subViewEnd(m_docContent, searchStart2, searchEnd2),
QStringView(QStringLiteral(">")));
if (closingAngleBracketPos == -1)
return;
@@ -2926,6 +3050,8 @@ void ExtraHighlightingResultsCollector::setResultPosFromRange(HighlightingResult
void ExtraHighlightingResultsCollector::collectFromNode(const AstNode &node)
{
+ if (node.kind() == "UserDefinedLiteral")
+ return;
if (node.kind().endsWith("Literal")) {
HighlightingResult result;
result.useTextSyles = true;
@@ -2969,16 +3095,14 @@ void ExtraHighlightingResultsCollector::collectFromNode(const AstNode &node)
// sub-expressions 2 and 3.
const int searchStartPosQuestionMark = posForNodeEnd(children.first());
const int searchEndPosQuestionMark = posForNodeStart(children.at(1));
- QStringView content = QStringView(m_docContent).mid(
- searchStartPosQuestionMark,
- searchEndPosQuestionMark - searchStartPosQuestionMark);
+ QStringView content = subViewEnd(m_docContent, searchStartPosQuestionMark,
+ searchEndPosQuestionMark);
const int questionMarkPos = onlyIndexOf(content, QStringView(QStringLiteral("?")));
if (questionMarkPos == -1)
return;
const int searchStartPosColon = posForNodeEnd(children.at(1));
const int searchEndPosColon = posForNodeStart(children.at(2));
- content = QStringView(m_docContent).mid(searchStartPosColon,
- searchEndPosColon - searchStartPosColon);
+ content = subViewEnd(m_docContent, searchStartPosColon, searchEndPosColon);
const int colonPos = onlyIndexOf(content, QStringView(QStringLiteral(":")));
if (colonPos == -1)
return;
@@ -3155,8 +3279,7 @@ void ExtraHighlightingResultsCollector::collectFromNode(const AstNode &node)
if (isDeclaration)
result.textStyles.mixinStyles.push_back(C_DECLARATION);
- const QStringView nodeText = QStringView(m_docContent)
- .mid(nodeStartPos, nodeEndPos - nodeStartPos);
+ const QStringView nodeText = subViewEnd(m_docContent, nodeStartPos, nodeEndPos);
if (isCallToNew || isCallToDelete) {
result.line = node.range().start().line() + 1;
@@ -3255,12 +3378,22 @@ void ExtraHighlightingResultsCollector::visitNode(const AstNode &node)
{
if (m_future.isCanceled())
return;
- collectFromNode(node);
- const auto children = node.children();
- if (!children)
+ switch (node.fileStatus(m_filePath)) {
+ case AstNode::FileStatus::Foreign:
return;
- for (const AstNode &childNode : *children)
- visitNode(childNode);
+ case AstNode::FileStatus::Ours:
+ case AstNode::FileStatus::Unknown:
+ collectFromNode(node);
+ [[fallthrough]];
+ case ClangCodeModel::Internal::AstNode::FileStatus::Mixed: {
+ const auto children = node.children();
+ if (!children)
+ return;
+ for (const AstNode &childNode : *children)
+ visitNode(childNode);
+ break;
+ }
+ }
}
} // namespace Internal
diff --git a/src/plugins/clangcodemodel/clangdiagnostictooltipwidget.cpp b/src/plugins/clangcodemodel/clangdiagnostictooltipwidget.cpp
index ffdd3c4396..195c4f4ead 100644
--- a/src/plugins/clangcodemodel/clangdiagnostictooltipwidget.cpp
+++ b/src/plugins/clangcodemodel/clangdiagnostictooltipwidget.cpp
@@ -104,9 +104,9 @@ public:
}
QWidget *createWidget(const QVector<ClangBackEnd::DiagnosticContainer> &diagnostics,
- const std::function<bool()> &canApplyFixIt)
+ const std::function<bool()> &canApplyFixIt, const QString &source)
{
- const QString text = htmlText(diagnostics);
+ const QString text = htmlText(diagnostics, source);
auto *label = new QLabel;
label->setTextFormat(Qt::RichText);
@@ -154,13 +154,20 @@ public:
return label;
}
- QString htmlText(const QVector<ClangBackEnd::DiagnosticContainer> &diagnostics)
+ QString htmlText(const QVector<ClangBackEnd::DiagnosticContainer> &diagnostics,
+ const QString &source)
{
// For debugging, add: style='border-width:1px;border-color:black'
QString text = "<table cellspacing='0' cellpadding='0' width='100%'>";
foreach (const ClangBackEnd::DiagnosticContainer &diagnostic, diagnostics)
text.append(tableRows(diagnostic));
+ if (!source.isEmpty()) {
+ text.append(QString::fromUtf8("<tr><td colspan='2' align='left'>"
+ "<font color='gray'>%1</font></td></tr>")
+ .arg(QCoreApplication::translate("ClangDiagnosticWidget", "[Source: %1]"))
+ .arg(source));
+ }
text.append("</table>");
@@ -396,7 +403,8 @@ QString ClangDiagnosticWidget::createText(
const QVector<ClangBackEnd::DiagnosticContainer> &diagnostics,
const ClangDiagnosticWidget::Destination &destination)
{
- const QString htmlText = WidgetFromDiagnostics(toHints(destination, {})).htmlText(diagnostics);
+ const QString htmlText = WidgetFromDiagnostics(toHints(destination, {}))
+ .htmlText(diagnostics, {});
QTextDocument document;
document.setHtml(htmlText);
@@ -410,11 +418,13 @@ QString ClangDiagnosticWidget::createText(
return text;
}
-QWidget *ClangDiagnosticWidget::createWidget(const QVector<ClangBackEnd::DiagnosticContainer> &diagnostics,
- const Destination &destination, const std::function<bool()> &canApplyFixIt)
+QWidget *ClangDiagnosticWidget::createWidget(
+ const QVector<ClangBackEnd::DiagnosticContainer> &diagnostics,
+ const Destination &destination, const std::function<bool()> &canApplyFixIt,
+ const QString &source)
{
return WidgetFromDiagnostics(toHints(destination, canApplyFixIt))
- .createWidget(diagnostics, canApplyFixIt);
+ .createWidget(diagnostics, canApplyFixIt, source);
}
} // namespace Internal
diff --git a/src/plugins/clangcodemodel/clangdiagnostictooltipwidget.h b/src/plugins/clangcodemodel/clangdiagnostictooltipwidget.h
index afe35812ae..92f98a59ca 100644
--- a/src/plugins/clangcodemodel/clangdiagnostictooltipwidget.h
+++ b/src/plugins/clangcodemodel/clangdiagnostictooltipwidget.h
@@ -48,7 +48,8 @@ public:
static QWidget *createWidget(const QVector<ClangBackEnd::DiagnosticContainer> &diagnostics,
const Destination &destination,
- const std::function<bool()> &canApplyFixIt);
+ const std::function<bool()> &canApplyFixIt,
+ const QString &source);
};
} // namespace Internal
diff --git a/src/plugins/clangcodemodel/clangeditordocumentprocessor.cpp b/src/plugins/clangcodemodel/clangeditordocumentprocessor.cpp
index a9d4f01c72..94a4408505 100644
--- a/src/plugins/clangcodemodel/clangeditordocumentprocessor.cpp
+++ b/src/plugins/clangcodemodel/clangeditordocumentprocessor.cpp
@@ -506,7 +506,8 @@ ClangEditorDocumentProcessor::creatorForHeaderErrorDiagnosticWidget(
vbox->setSpacing(2);
vbox->addWidget(ClangDiagnosticWidget::createWidget({firstHeaderErrorDiagnostic},
- ClangDiagnosticWidget::InfoBar, {}));
+ ClangDiagnosticWidget::InfoBar, {},
+ "libclang"));
auto widget = new QWidget;
widget->setLayout(vbox);
diff --git a/src/plugins/clangcodemodel/clangmodelmanagersupport.cpp b/src/plugins/clangcodemodel/clangmodelmanagersupport.cpp
index 52be361305..d1c6b0d0ce 100644
--- a/src/plugins/clangcodemodel/clangmodelmanagersupport.cpp
+++ b/src/plugins/clangcodemodel/clangmodelmanagersupport.cpp
@@ -286,7 +286,7 @@ void ClangModelManagerSupport::updateLanguageClient(
if (const ProjectExplorer::Target * const target = project->activeTarget()) {
if (const ProjectExplorer::BuildConfiguration * const bc
= target->activeBuildConfiguration()) {
- return bc->buildDirectory();
+ return bc->buildDirectory() / ".qtc_clangd";
}
}
return Utils::FilePath();
@@ -363,7 +363,7 @@ void ClangModelManagerSupport::updateLanguageClient(
});
});
- auto future = Utils::runAsync(&Internal::generateCompilationDB, projectInfo,
+ auto future = Utils::runAsync(&Internal::generateCompilationDB, projectInfo, jsonDbDir,
CompilationDbPurpose::CodeModel,
warningsConfigForProject(project),
optionsForProject(project));
@@ -483,10 +483,6 @@ void ClangModelManagerSupport::onEditorOpened(Core::IEditor *editor)
// TODO: Ensure that not fully loaded documents are updated?
- // TODO: If the file does not belong to any project and it is a header file,
- // it might make sense to check whether the file is included by any file
- // that does belong to a project, and if so, use the respective client
- // instead. Is this feasible?
ProjectExplorer::Project * const project
= ProjectExplorer::SessionManager::projectForFile(document->filePath());
if (ClangdClient * const client = clientForProject(project))
diff --git a/src/plugins/clangcodemodel/clangtextmark.cpp b/src/plugins/clangcodemodel/clangtextmark.cpp
index 38227008a9..01cfae6ae6 100644
--- a/src/plugins/clangcodemodel/clangtextmark.cpp
+++ b/src/plugins/clangcodemodel/clangtextmark.cpp
@@ -281,7 +281,7 @@ bool ClangTextMark::addToolTipContent(QLayout *target) const
&& diagMgr->diagnosticsWithFixIts().contains(diag);
};
QWidget *widget = ClangDiagnosticWidget::createWidget(
- {m_diagnostic}, ClangDiagnosticWidget::ToolTip, canApplyFixIt);
+ {m_diagnostic}, ClangDiagnosticWidget::ToolTip, canApplyFixIt, "libclang");
target->addWidget(widget);
return true;
@@ -398,7 +398,7 @@ bool ClangdTextMark::addToolTipContent(QLayout *target) const
return c && c->reachable() && c->hasDiagnostic(DocumentUri::fromFilePath(fp), diag);
};
target->addWidget(ClangDiagnosticWidget::createWidget({m_diagnostic},
- ClangDiagnosticWidget::ToolTip, canApplyFixIt));
+ ClangDiagnosticWidget::ToolTip, canApplyFixIt, "clangd"));
return true;
}
diff --git a/src/plugins/clangcodemodel/clangutils.cpp b/src/plugins/clangcodemodel/clangutils.cpp
index bbe9817380..a089248d03 100644
--- a/src/plugins/clangcodemodel/clangutils.cpp
+++ b/src/plugins/clangcodemodel/clangutils.cpp
@@ -372,18 +372,15 @@ static QJsonObject createFileObject(const FilePath &buildDir,
}
GenerateCompilationDbResult generateCompilationDB(const CppEditor::ProjectInfo::ConstPtr projectInfo,
+ const Utils::FilePath &baseDir,
CompilationDbPurpose purpose,
const ClangDiagnosticConfig &warningsConfig,
const QStringList &projectOptions)
{
- const FilePath buildDir = projectInfo->buildRoot();
- QTC_ASSERT(!buildDir.isEmpty(), return GenerateCompilationDbResult(QString(),
+ QTC_ASSERT(!baseDir.isEmpty(), return GenerateCompilationDbResult(QString(),
QCoreApplication::translate("ClangUtils", "Could not retrieve build directory.")));
-
- QDir dir(buildDir.toString());
- if (!dir.exists())
- dir.mkpath(dir.path());
- QFile compileCommandsFile(buildDir.toString() + "/compile_commands.json");
+ QTC_CHECK(baseDir.ensureWritableDir());
+ QFile compileCommandsFile(baseDir.toString() + "/compile_commands.json");
const bool fileOpened = compileCommandsFile.open(QIODevice::WriteOnly | QIODevice::Truncate);
if (!fileOpened) {
return GenerateCompilationDbResult(QString(),
@@ -397,7 +394,7 @@ GenerateCompilationDbResult generateCompilationDB(const CppEditor::ProjectInfo::
if (purpose == CompilationDbPurpose::Project)
args = projectPartArguments(*projectPart);
for (const ProjectFile &projFile : projectPart->files) {
- const QJsonObject json = createFileObject(buildDir, args, *projectPart, projFile,
+ const QJsonObject json = createFileObject(baseDir, args, *projectPart, projFile,
purpose, warningsConfig, projectOptions);
if (compileCommandsFile.size() > 1)
compileCommandsFile.write(",");
diff --git a/src/plugins/clangcodemodel/clangutils.h b/src/plugins/clangcodemodel/clangutils.h
index 1d46e6a49b..c3a496f779 100644
--- a/src/plugins/clangcodemodel/clangutils.h
+++ b/src/plugins/clangcodemodel/clangutils.h
@@ -88,8 +88,8 @@ public:
enum class CompilationDbPurpose { Project, CodeModel };
GenerateCompilationDbResult generateCompilationDB(const CppEditor::ProjectInfo::ConstPtr projectInfo,
- CompilationDbPurpose purpose, const CppEditor::ClangDiagnosticConfig &warningsConfig,
- const QStringList &projectOptions);
+ const Utils::FilePath &baseDir, CompilationDbPurpose purpose,
+ const CppEditor::ClangDiagnosticConfig &warningsConfig, const QStringList &projectOptions);
class DiagnosticTextInfo
{
diff --git a/src/plugins/clangformat/clangformatfile.cpp b/src/plugins/clangformat/clangformatfile.cpp
index 8e532ea797..c9955ef2a3 100644
--- a/src/plugins/clangformat/clangformatfile.cpp
+++ b/src/plugins/clangformat/clangformatfile.cpp
@@ -105,7 +105,7 @@ void ClangFormatFile::saveNewFormat()
// workaround: configurationAsText() add comment "# " before BasedOnStyle line
const int pos = style.find("# BasedOnStyle");
- if (pos < style.size())
+ if (pos < int(style.size()))
style.erase(pos, 2);
m_filePath.writeFileContents(QByteArray::fromStdString(style));
}
diff --git a/src/plugins/clangtools/clangtoolsdiagnostic.cpp b/src/plugins/clangtools/clangtoolsdiagnostic.cpp
index 7fe7098c22..42ec9f5f2a 100644
--- a/src/plugins/clangtools/clangtoolsdiagnostic.cpp
+++ b/src/plugins/clangtools/clangtoolsdiagnostic.cpp
@@ -62,7 +62,7 @@ QIcon Diagnostic::icon() const
return {};
}
-quint32 qHash(const Diagnostic &diagnostic)
+Utils::QHashValueType qHash(const Diagnostic &diagnostic)
{
return qHash(diagnostic.name)
^ qHash(diagnostic.description)
diff --git a/src/plugins/clangtools/clangtoolsdiagnostic.h b/src/plugins/clangtools/clangtoolsdiagnostic.h
index e64d91a29f..10534ff0b2 100644
--- a/src/plugins/clangtools/clangtoolsdiagnostic.h
+++ b/src/plugins/clangtools/clangtoolsdiagnostic.h
@@ -27,6 +27,8 @@
#include <debugger/analyzer/diagnosticlocation.h>
+#include <utils/porting.h>
+
#include <QMetaType>
#include <QString>
#include <QVector>
@@ -68,7 +70,7 @@ bool operator==(const Diagnostic &lhs, const Diagnostic &rhs);
using Diagnostics = QList<Diagnostic>;
-quint32 qHash(const Diagnostic &diagnostic);
+Utils::QHashValueType qHash(const Diagnostic &diagnostic);
} // namespace Internal
} // namespace ClangTools
diff --git a/src/plugins/clearcase/clearcaseplugin.cpp b/src/plugins/clearcase/clearcaseplugin.cpp
index 6d0486650f..a878f8864c 100644
--- a/src/plugins/clearcase/clearcaseplugin.cpp
+++ b/src/plugins/clearcase/clearcaseplugin.cpp
@@ -1826,12 +1826,8 @@ bool ClearCasePluginPrivate::vcsOpen(const FilePath &workingDir, const QString &
setStatus(absPath, FileStatus::CheckedOut);
}
- foreach (DocumentModel::Entry *e, DocumentModel::entries()) {
- if (e->fileName().toString() == absPath) {
- e->document->checkPermissions();
- break;
- }
- }
+ if (DocumentModel::Entry *e = DocumentModel::entryForFilePath(FilePath::fromString(absPath)))
+ e->document->checkPermissions();
return !response.error;
}
diff --git a/src/plugins/cmakeprojectmanager/cmakebuildsystem.cpp b/src/plugins/cmakeprojectmanager/cmakebuildsystem.cpp
index d1c9d9a22b..4eb6fdc97f 100644
--- a/src/plugins/cmakeprojectmanager/cmakebuildsystem.cpp
+++ b/src/plugins/cmakeprojectmanager/cmakebuildsystem.cpp
@@ -934,18 +934,10 @@ void CMakeBuildSystem::runCTest()
process.setCommand(cmd);
process.start();
- if (!process.waitForStarted(1000) || !process.waitForFinished()) {
- if (process.state() == QProcess::NotRunning)
- return;
- process.terminate();
- if (process.waitForFinished(1000))
- return;
- process.kill();
- process.waitForFinished(1000);
+ if (!process.waitForStarted(1000) || !process.waitForFinished()
+ || process.exitCode() || process.exitStatus() != QProcess::NormalExit) {
return;
}
- if (process.exitCode() || process.exitStatus() != QProcess::NormalExit)
- return;
futureInterface.reportResult(process.readAllStandardOutput());
});
diff --git a/src/plugins/cmakeprojectmanager/cmakeconfigitem.cpp b/src/plugins/cmakeprojectmanager/cmakeconfigitem.cpp
index 93e6e6232a..bd5556d215 100644
--- a/src/plugins/cmakeprojectmanager/cmakeconfigitem.cpp
+++ b/src/plugins/cmakeprojectmanager/cmakeconfigitem.cpp
@@ -472,7 +472,7 @@ bool CMakeConfigItem::operator==(const CMakeConfigItem &o) const
return o.key == key && o.value == value && o.isUnset == isUnset;
}
-uint qHash(const CMakeConfigItem &it)
+Utils::QHashValueType qHash(const CMakeConfigItem &it)
{
return ::qHash(it.key) ^ ::qHash(it.value) ^ ::qHash(it.isUnset);
}
diff --git a/src/plugins/cmakeprojectmanager/cmakeconfigitem.h b/src/plugins/cmakeprojectmanager/cmakeconfigitem.h
index dae93455d7..19bbbfd7d6 100644
--- a/src/plugins/cmakeprojectmanager/cmakeconfigitem.h
+++ b/src/plugins/cmakeprojectmanager/cmakeconfigitem.h
@@ -27,6 +27,7 @@
#include "cmake_global.h"
+#include <utils/porting.h>
#include <utils/optional.h>
#include <QByteArray>
@@ -78,7 +79,7 @@ public:
QStringList values;
};
-uint qHash(const CMakeConfigItem &it); // needed for MSVC
+Utils::QHashValueType qHash(const CMakeConfigItem &it); // needed for MSVC
class CMAKE_EXPORT CMakeConfig : public QList<CMakeConfigItem>
{
diff --git a/src/plugins/cmakeprojectmanager/cmakeprocess.cpp b/src/plugins/cmakeprojectmanager/cmakeprocess.cpp
index 64e59109dd..d8f24b4362 100644
--- a/src/plugins/cmakeprojectmanager/cmakeprocess.cpp
+++ b/src/plugins/cmakeprojectmanager/cmakeprocess.cpp
@@ -92,10 +92,8 @@ void CMakeProcess::run(const BuildDirParameters &parameters, const QStringList &
}
}
- const QString srcDir = parameters.sourceDirectory.path();
-
const auto parser = new CMakeParser;
- parser->setSourceDirectory(srcDir);
+ parser->setSourceDirectory(parameters.sourceDirectory.path());
m_parser.addLineParser(parser);
// Always use the sourceDir: If we are triggered because the build directory is getting deleted
@@ -121,7 +119,13 @@ void CMakeProcess::run(const BuildDirParameters &parameters, const QStringList &
connect(process.get(), &QtcProcess::finished,
this, &CMakeProcess::handleProcessFinished);
- CommandLine commandLine(cmake->cmakeExecutable(), QStringList({"-S", srcDir, "-B", buildDirectory.path()}) + arguments);
+ const FilePath cmakeExecutable = cmake->cmakeExecutable();
+ const FilePath sourceDirectory = parameters.sourceDirectory.onDevice(cmakeExecutable);
+
+ CommandLine commandLine(cmakeExecutable);
+ commandLine.addArgs({"-S", sourceDirectory.mapToDevicePath(),
+ "-B", buildDirectory.mapToDevicePath()});
+ commandLine.addArgs(arguments);
TaskHub::clearTasks(ProjectExplorer::Constants::TASK_CATEGORY_BUILDSYSTEM);
diff --git a/src/plugins/cmakeprojectmanager/fileapidataextractor.cpp b/src/plugins/cmakeprojectmanager/fileapidataextractor.cpp
index cabac0b3b9..d5836605f4 100644
--- a/src/plugins/cmakeprojectmanager/fileapidataextractor.cpp
+++ b/src/plugins/cmakeprojectmanager/fileapidataextractor.cpp
@@ -28,9 +28,10 @@
#include "fileapiparser.h"
#include "projecttreehelper.h"
-#include <cppeditor/cppprojectfilecategorizer.h>
+#include <cppeditor/cppeditorconstants.h>
#include <utils/algorithm.h>
+#include <utils/mimetypes/mimedatabase.h>
#include <utils/qtcassert.h>
#include <utils/qtcprocess.h>
#include <utils/utilsicons.h>
@@ -336,16 +337,6 @@ RawProjectParts generateRawProjectParts(const PreprocessedData &input,
int counter = 0;
for (const TargetDetails &t : input.targetDetails) {
QDir sourceDir(sourceDirectory.toString());
-
- // Do not tread generated files and CMake precompiled headers as project files
- const auto sourceFiles = Utils::filtered(t.sources, [buildDirectory](const SourceInfo &si) {
- return !si.isGenerated && !isPchFile(buildDirectory, FilePath::fromString(si.path));
- });
- CppEditor::ProjectFileCategorizer
- categorizer({}, transform<QList>(sourceFiles, [&sourceDir](const SourceInfo &si) {
- return sourceDir.absoluteFilePath(si.path);
- }));
-
bool needPostfix = t.compileGroups.size() > 1;
int count = 1;
for (const CompileInfo &ci : t.compileGroups) {
@@ -387,20 +378,45 @@ RawProjectParts generateRawProjectParts(const PreprocessedData &input,
QStringList fragments = splitFragments(ci.fragments);
+ // Get all sources from the compiler group, except generated sources
+ QStringList sources;
+ for (auto idx: ci.sources) {
+ SourceInfo si = t.sources.at(idx);
+ if (si.isGenerated)
+ continue;
+ sources.push_back(sourceDir.absoluteFilePath(si.path));
+ }
+
+ // If we are not in a pch compiler group, add all the headers that are not generated
+ const bool hasPchSource = anyOf(sources, [buildDirectory](const QString &path) {
+ return isPchFile(buildDirectory, FilePath::fromString(path));
+ });
+ if (!hasPchSource) {
+ QString headerMimeType;
+ if (ci.language == "C")
+ headerMimeType = CppEditor::Constants::C_HEADER_MIMETYPE;
+ else if (ci.language == "CXX")
+ headerMimeType = CppEditor::Constants::CPP_HEADER_MIMETYPE;
+
+ for (const SourceInfo &si : t.sources) {
+ if (si.isGenerated)
+ continue;
+ const auto mimeTypes = Utils::mimeTypesForFileName(si.path);
+ for (auto mime : mimeTypes)
+ if (mime.name() == headerMimeType)
+ sources.push_back(sourceDir.absoluteFilePath(si.path));
+ }
+ }
+
+ // Set project files except pch files
+ rpp.setFiles(Utils::filtered(sources, [buildDirectory](const QString &path) {
+ return !isPchFile(buildDirectory, FilePath::fromString(path));
+ }));
+
FilePath precompiled_header
= FilePath::fromString(findOrDefault(t.sources, [&ending](const SourceInfo &si) {
return si.path.endsWith(ending);
}).path);
-
- CppEditor::ProjectFiles sources;
- if (ci.language == "C")
- sources = categorizer.cSources();
- else if (ci.language == "CXX")
- sources = categorizer.cxxSources();
-
- rpp.setFiles(transform<QList>(sources, [](const CppEditor::ProjectFile &pf) {
- return pf.path;
- }));
if (!precompiled_header.isEmpty()) {
if (precompiled_header.toFileInfo().isRelative()) {
const FilePath parentDir = FilePath::fromString(sourceDir.absolutePath());
@@ -595,9 +611,20 @@ void addTargets(const QHash<Utils::FilePath, ProjectExplorer::ProjectNode *> &cm
const FilePath &sourceDir,
const FilePath &buildDir)
{
+ QHash<QString, const TargetDetails *> targetDetailsHash;
+ for (const TargetDetails &t : targetDetails)
+ targetDetailsHash.insert(t.id, &t);
+ const TargetDetails defaultTargetDetails;
+ auto getTargetDetails = [&targetDetailsHash, &defaultTargetDetails](const QString &id)
+ -> const TargetDetails & {
+ auto it = targetDetailsHash.constFind(id);
+ if (it != targetDetailsHash.constEnd())
+ return *it.value();
+ return defaultTargetDetails;
+ };
+
for (const FileApiDetails::Target &t : config.targets) {
- const TargetDetails &td = Utils::findOrDefault(targetDetails,
- Utils::equal(&TargetDetails::id, t.id));
+ const TargetDetails &td = getTargetDetails(t.id);
const FilePath dir = directorySourceDir(config, sourceDir, t.directory);
@@ -730,7 +757,7 @@ FileApiQtcData extractData(FileApiData &input,
result.projectParts = generateRawProjectParts(data, sourceDirectory, buildDirectory);
auto rootProjectNode = generateRootProjectNode(data, sourceDirectory, buildDirectory);
- ProjectTree::applyTreeManager(rootProjectNode.get()); // QRC nodes
+ ProjectTree::applyTreeManager(rootProjectNode.get(), ProjectTree::AsyncPhase); // QRC nodes
result.rootProjectNode = std::move(rootProjectNode);
setupLocationInfoForTargets(result.rootProjectNode.get(), result.buildTargets);
diff --git a/src/plugins/cmakeprojectmanager/fileapidataextractor.h b/src/plugins/cmakeprojectmanager/fileapidataextractor.h
index 2b65c76e07..1bc99bf1a8 100644
--- a/src/plugins/cmakeprojectmanager/fileapidataextractor.h
+++ b/src/plugins/cmakeprojectmanager/fileapidataextractor.h
@@ -56,7 +56,7 @@ public:
bool isGenerated = false;
};
-inline uint qHash(const CMakeFileInfo &info, uint seed = 0) { return info.path.hash(seed); }
+inline auto qHash(const CMakeFileInfo &info, uint seed = 0) { return info.path.hash(seed); }
class FileApiQtcData
{
diff --git a/src/plugins/coreplugin/dialogs/codecselector.cpp b/src/plugins/coreplugin/dialogs/codecselector.cpp
index a84b0fa112..9b5786c1b4 100644
--- a/src/plugins/coreplugin/dialogs/codecselector.cpp
+++ b/src/plugins/coreplugin/dialogs/codecselector.cpp
@@ -87,6 +87,8 @@ CodecSelector::CodecSelector(QWidget *parent, Core::BaseTextDocument *doc)
int currentIndex = -1;
foreach (int mib, sortedMibs) {
QTextCodec *c = QTextCodec::codecForMib(mib);
+ if (!doc->supportsCodec(c))
+ continue;
if (!buf.isEmpty()) {
// slow, should use a feature from QTextCodec or QTextDecoder (but those are broken currently)
diff --git a/src/plugins/coreplugin/documentmanager.cpp b/src/plugins/coreplugin/documentmanager.cpp
index 6fa127e255..4fd4213dbb 100644
--- a/src/plugins/coreplugin/documentmanager.cpp
+++ b/src/plugins/coreplugin/documentmanager.cpp
@@ -55,6 +55,7 @@
#include <utils/pathchooser.h>
#include <utils/qtcassert.h>
#include <utils/reloadpromptutils.h>
+#include <utils/threadutils.h>
#include <QStringList>
#include <QDateTime>
@@ -326,6 +327,7 @@ static void addFileInfo(IDocument *document, const FilePath &filePath, const Fil
(The added file names are guaranteed to be absolute and cleaned.) */
static void addFileInfos(const QList<IDocument *> &documents)
{
+ QTC_ASSERT(isMainThread(), return);
FilePaths pathsToWatch;
FilePaths linkPathsToWatch;
for (IDocument *document : documents) {
@@ -400,6 +402,7 @@ void DocumentManager::addDocuments(const QList<IDocument *> &documents, bool add
*/
static void removeFileInfo(IDocument *document)
{
+ QTC_ASSERT(isMainThread(), return);
if (!d->m_documentsWithWatch.contains(document))
return;
foreach (const FilePath &filePath, d->m_documentsWithWatch.value(document)) {
@@ -1186,10 +1189,10 @@ void DocumentManager::checkForReload()
bool success = true;
QString errorString;
// we've got some modification
+ document->checkPermissions();
// check if it's contents or permissions:
if (!type) {
// Only permission change
- document->checkPermissions();
success = true;
// now we know it's a content change or file was removed
} else if (defaultBehavior == IDocument::ReloadUnmodified && type == IDocument::TypeContents
diff --git a/src/plugins/coreplugin/editormanager/editormanager.cpp b/src/plugins/coreplugin/editormanager/editormanager.cpp
index c2b432d05a..7944c88285 100644
--- a/src/plugins/coreplugin/editormanager/editormanager.cpp
+++ b/src/plugins/coreplugin/editormanager/editormanager.cpp
@@ -2110,7 +2110,7 @@ void EditorManagerPrivate::updateWindowTitleForDocument(IDocument *document, QWi
if (!documentName.isEmpty())
windowTitle.append(documentName);
- const QString filePath = document ? document->filePath().toFileInfo().absoluteFilePath()
+ const QString filePath = document ? document->filePath().absoluteFilePath().path()
: QString();
const QString windowTitleAddition = d->m_titleAdditionHandler
? d->m_titleAdditionHandler(filePath)
diff --git a/src/plugins/coreplugin/locator/ilocatorfilter.h b/src/plugins/coreplugin/locator/ilocatorfilter.h
index bc44cfb1f7..4867987869 100644
--- a/src/plugins/coreplugin/locator/ilocatorfilter.h
+++ b/src/plugins/coreplugin/locator/ilocatorfilter.h
@@ -31,9 +31,10 @@
#include <utils/id.h>
#include <utils/optional.h>
-#include <QVariant>
#include <QFutureInterface>
#include <QIcon>
+#include <QMetaType>
+#include <QVariant>
namespace Core {
@@ -74,12 +75,6 @@ struct LocatorFilterEntry
, displayIcon(icon)
{}
- bool operator==(const LocatorFilterEntry &other) const {
- if (internalData.canConvert(QVariant::String))
- return (internalData.toString() == other.internalData.toString());
- return internalData.constData() == other.internalData.constData();
- }
-
/* backpointer to creating filter */
ILocatorFilter *filter = nullptr;
/* displayed string */
diff --git a/src/plugins/coreplugin/locator/locatorsearchutils.cpp b/src/plugins/coreplugin/locator/locatorsearchutils.cpp
index a9eb1a7de2..cefe9481c0 100644
--- a/src/plugins/coreplugin/locator/locatorsearchutils.cpp
+++ b/src/plugins/coreplugin/locator/locatorsearchutils.cpp
@@ -29,21 +29,10 @@
#include <QString>
#include <QVariant>
-namespace Core {
-
-uint qHash(const LocatorFilterEntry &entry)
-{
- if (entry.internalData.canConvert(QVariant::String))
- return QT_PREPEND_NAMESPACE(qHash)(entry.internalData.toString());
- return QT_PREPEND_NAMESPACE(qHash)(entry.internalData.constData());
-}
-
-} // namespace Core
-
void Core::Internal::runSearch(QFutureInterface<Core::LocatorFilterEntry> &future,
const QList<ILocatorFilter *> &filters, const QString &searchText)
{
- QSet<LocatorFilterEntry> alreadyAdded;
+ QSet<QString> alreadyAdded;
const bool checkDuplicates = (filters.size() > 1);
for (ILocatorFilter *filter : filters) {
if (future.isCanceled())
@@ -53,11 +42,15 @@ void Core::Internal::runSearch(QFutureInterface<Core::LocatorFilterEntry> &futur
QVector<LocatorFilterEntry> uniqueFilterResults;
uniqueFilterResults.reserve(filterResults.size());
for (const LocatorFilterEntry &entry : filterResults) {
- if (checkDuplicates && alreadyAdded.contains(entry))
- continue;
+ if (checkDuplicates) {
+ const QString stringData = entry.internalData.toString();
+ if (!stringData.isEmpty()) {
+ if (alreadyAdded.contains(stringData))
+ continue;
+ alreadyAdded.insert(stringData);
+ }
+ }
uniqueFilterResults.append(entry);
- if (checkDuplicates)
- alreadyAdded.insert(entry);
}
if (!uniqueFilterResults.isEmpty())
future.reportResults(uniqueFilterResults);
diff --git a/src/plugins/coreplugin/manhattanstyle.cpp b/src/plugins/coreplugin/manhattanstyle.cpp
index 50837d9f15..a6b94660f6 100644
--- a/src/plugins/coreplugin/manhattanstyle.cpp
+++ b/src/plugins/coreplugin/manhattanstyle.cpp
@@ -73,10 +73,13 @@ bool styleEnabled(const QWidget *widget)
return true;
}
-static bool isInDialogOrPopup(const QWidget *widget)
+static bool isInUnstyledDialogOrPopup(const QWidget *widget)
{
- // Do not style dialogs or explicitly ignored widgets
- const Qt::WindowType windowType = widget->window()->windowType();
+ // Do not style contents of dialogs or popups without "panelwidget" property
+ const QWidget *window = widget->window();
+ if (window->property("panelwidget").toBool())
+ return false;
+ const Qt::WindowType windowType = window->windowType();
return (windowType == Qt::Dialog || windowType == Qt::Popup);
}
@@ -86,7 +89,7 @@ bool panelWidget(const QWidget *widget)
if (!widget)
return false;
- if (isInDialogOrPopup(widget))
+ if (isInUnstyledDialogOrPopup(widget))
return false;
if (qobject_cast<const FancyMainWindow *>(widget))
@@ -113,7 +116,7 @@ bool lightColored(const QWidget *widget)
if (!widget)
return false;
- if (isInDialogOrPopup(widget))
+ if (isInUnstyledDialogOrPopup(widget))
return false;
const QWidget *p = widget;
diff --git a/src/plugins/coreplugin/textdocument.cpp b/src/plugins/coreplugin/textdocument.cpp
index 4d6c45dadf..448854926d 100644
--- a/src/plugins/coreplugin/textdocument.cpp
+++ b/src/plugins/coreplugin/textdocument.cpp
@@ -183,7 +183,13 @@ void BaseTextDocument::setCodec(const QTextCodec *codec)
{
if (debug)
qDebug() << Q_FUNC_INFO << this << (codec ? codec->name() : QByteArray());
- d->m_format.codec = codec;
+ if (supportsCodec(codec))
+ d->m_format.codec = codec;
+}
+
+bool BaseTextDocument::supportsCodec(const QTextCodec *) const
+{
+ return true;
}
void BaseTextDocument::switchUtf8Bom()
diff --git a/src/plugins/coreplugin/textdocument.h b/src/plugins/coreplugin/textdocument.h
index 7d16b6fa81..83450b8395 100644
--- a/src/plugins/coreplugin/textdocument.h
+++ b/src/plugins/coreplugin/textdocument.h
@@ -46,6 +46,7 @@ public:
Utils::TextFileFormat format() const;
const QTextCodec *codec() const;
void setCodec(const QTextCodec *);
+ virtual bool supportsCodec(const QTextCodec *) const;
void switchUtf8Bom();
bool supportsUtf8Bom() const;
Utils::TextFileFormat::LineTerminationMode lineTerminationMode() const;
diff --git a/src/plugins/cppcheck/cppcheckdiagnostic.cpp b/src/plugins/cppcheck/cppcheckdiagnostic.cpp
index 6534018fc5..a1b8235e82 100644
--- a/src/plugins/cppcheck/cppcheckdiagnostic.cpp
+++ b/src/plugins/cppcheck/cppcheckdiagnostic.cpp
@@ -34,7 +34,7 @@ bool Diagnostic::operator==(const Diagnostic &r) const
== std::tie(r.severity, r.message, r.fileName, r.lineNumber);
}
-quint32 qHash(const Diagnostic &diagnostic)
+Utils::QHashValueType qHash(const Diagnostic &diagnostic)
{
return qHash(diagnostic.message) ^ qHash(diagnostic.fileName) ^ diagnostic.lineNumber;
}
diff --git a/src/plugins/cppcheck/cppcheckdiagnostic.h b/src/plugins/cppcheck/cppcheckdiagnostic.h
index eea6ef430e..1983af68de 100644
--- a/src/plugins/cppcheck/cppcheckdiagnostic.h
+++ b/src/plugins/cppcheck/cppcheckdiagnostic.h
@@ -26,6 +26,7 @@
#pragma once
#include <utils/fileutils.h>
+#include <utils/porting.h>
namespace Cppcheck {
namespace Internal {
@@ -49,7 +50,7 @@ public:
int lineNumber = 0;
};
-quint32 qHash(const Diagnostic &diagnostic);
+Utils::QHashValueType qHash(const Diagnostic &diagnostic);
} // namespace Internal
} // namespace Cppcheck
diff --git a/src/plugins/cppeditor/compileroptionsbuilder.cpp b/src/plugins/cppeditor/compileroptionsbuilder.cpp
index 14921c51eb..09f71fa93f 100644
--- a/src/plugins/cppeditor/compileroptionsbuilder.cpp
+++ b/src/plugins/cppeditor/compileroptionsbuilder.cpp
@@ -123,7 +123,7 @@ CompilerOptionsBuilder::~CompilerOptionsBuilder() = default;
QStringList CompilerOptionsBuilder::build(ProjectFile::Kind fileKind,
UsePrecompiledHeaders usePrecompiledHeaders)
{
- m_options.clear();
+ reset();
evaluateCompilerFlags();
if (fileKind == ProjectFile::CHeader || fileKind == ProjectFile::CSource) {
@@ -251,9 +251,12 @@ void CompilerOptionsBuilder::addWordWidth()
void CompilerOptionsBuilder::addTargetTriple()
{
+ const QString target = m_explicitTarget.isEmpty()
+ ? m_projectPart.toolChainTargetTriple : m_explicitTarget;
+
// Only "--target=" style is accepted in both g++ and cl driver modes.
- if (!m_projectPart.toolChainTargetTriple.isEmpty())
- add("--target=" + m_projectPart.toolChainTargetTriple);
+ if (!target.isEmpty())
+ add("--target=" + target);
}
void CompilerOptionsBuilder::addExtraCodeModelFlags()
@@ -771,6 +774,7 @@ void CompilerOptionsBuilder::undefineClangVersionMacrosForMsvc()
void CompilerOptionsBuilder::reset()
{
m_options.clear();
+ m_explicitTarget.clear();
}
// Some example command lines for a "Qt Console Application":
@@ -786,12 +790,18 @@ void CompilerOptionsBuilder::evaluateCompilerFlags()
const Id toolChain = m_projectPart.toolchainType;
bool containsDriverMode = false;
bool skipNext = false;
- const QStringList allFlags = m_projectPart.compilerFlags + m_projectPart.extraCodeModelFlags;
+ bool nextIsTarget = false;
+ const QStringList allFlags = m_projectPart.extraCodeModelFlags + m_projectPart.compilerFlags;
for (const QString &option : allFlags) {
if (skipNext) {
skipNext = false;
continue;
}
+ if (nextIsTarget) {
+ nextIsTarget = false;
+ m_explicitTarget = option;
+ continue;
+ }
if (userBlackList.contains(option))
continue;
@@ -812,14 +822,15 @@ void CompilerOptionsBuilder::evaluateCompilerFlags()
continue;
}
- // As we always set the target explicitly, filter out target args.
- if (!m_projectPart.toolChainTargetTriple.isEmpty()) {
- if (option.startsWith("--target="))
- continue;
- if (option == "-target") {
- skipNext = true;
- continue;
- }
+ // An explicit target triple from the build system takes precedence over the generic one
+ // from the toolchain.
+ if (option.startsWith("--target=")) {
+ m_explicitTarget = option.mid(9);
+ continue;
+ }
+ if (option == "-target") {
+ nextIsTarget = true;
+ continue;
}
if (option == includeUserPathOption || option == includeSystemPathOption
diff --git a/src/plugins/cppeditor/compileroptionsbuilder.h b/src/plugins/cppeditor/compileroptionsbuilder.h
index 0211d58a18..cc75e984be 100644
--- a/src/plugins/cppeditor/compileroptionsbuilder.h
+++ b/src/plugins/cppeditor/compileroptionsbuilder.h
@@ -122,6 +122,7 @@ private:
} m_compilerFlags;
QStringList m_options;
+ QString m_explicitTarget;
bool m_clStyle = false;
};
diff --git a/src/plugins/cppeditor/cppcodemodelsettings.cpp b/src/plugins/cppeditor/cppcodemodelsettings.cpp
index 1a7cf1255f..66c07bed7a 100644
--- a/src/plugins/cppeditor/cppcodemodelsettings.cpp
+++ b/src/plugins/cppeditor/cppcodemodelsettings.cpp
@@ -402,7 +402,8 @@ QVariantMap ClangdSettings::Data::toMap() const
{
QVariantMap map;
map.insert(useClangdKey(), useClangd);
- map.insert(clangdPathKey(), executableFilePath.toString());
+ if (executableFilePath != fallbackClangdFilePath())
+ map.insert(clangdPathKey(), executableFilePath.toString());
map.insert(clangdIndexingKey(), enableIndexing);
map.insert(clangdThreadLimitKey(), workerThreadLimit);
map.insert(clangdDocumentThresholdKey(), documentUpdateThreshold);
diff --git a/src/plugins/cppeditor/cppcodemodelsettingspage.cpp b/src/plugins/cppeditor/cppcodemodelsettingspage.cpp
index 2c775e3843..1c6621e070 100644
--- a/src/plugins/cppeditor/cppcodemodelsettingspage.cpp
+++ b/src/plugins/cppeditor/cppcodemodelsettingspage.cpp
@@ -33,11 +33,14 @@
#include <coreplugin/icore.h>
#include <utils/algorithm.h>
+#include <utils/infolabel.h>
#include <utils/pathchooser.h>
+#include <utils/qtcprocess.h>
#include <QFormLayout>
#include <QSpinBox>
#include <QTextStream>
+#include <QVersionNumber>
namespace CppEditor::Internal {
@@ -197,6 +200,7 @@ public:
QSpinBox threadLimitSpinBox;
QSpinBox documentUpdateThreshold;
Utils::PathChooser clangdChooser;
+ Utils::InfoLabel versionWarningLabel;
};
ClangdSettingsWidget::ClangdSettingsWidget(const ClangdSettings::Data &settingsData)
@@ -230,6 +234,7 @@ ClangdSettingsWidget::ClangdSettingsWidget(const ClangdSettings::Data &settingsD
const auto formLayout = new QFormLayout;
const auto chooserLabel = new QLabel(tr("Path to executable:"));
formLayout->addRow(chooserLabel, &d->clangdChooser);
+ formLayout->addRow(QString(), &d->versionWarningLabel);
const auto indexingLabel = new QLabel(tr("Enable background indexing:"));
formLayout->addRow(indexingLabel, &d->indexingCheckBox);
const auto threadLimitLayout = new QHBoxLayout;
@@ -251,11 +256,58 @@ ClangdSettingsWidget::ClangdSettingsWidget(const ClangdSettings::Data &settingsD
indexingLabel->setEnabled(checked);
d->indexingCheckBox.setEnabled(checked);
d->threadLimitSpinBox.setEnabled(checked);
+ d->versionWarningLabel.setEnabled(checked);
};
connect(&d->useClangdCheckBox, &QCheckBox::toggled, toggleEnabled);
toggleEnabled(d->useClangdCheckBox.isChecked());
d->threadLimitSpinBox.setEnabled(d->useClangdCheckBox.isChecked());
+ d->versionWarningLabel.setType(Utils::InfoLabel::Warning);
+ const auto updateWarningLabel = [this] {
+ class WarningLabelSetter {
+ public:
+ WarningLabelSetter(QLabel &label) : m_label(label) { m_label.clear(); }
+ ~WarningLabelSetter() { m_label.setVisible(!m_label.text().isEmpty()); }
+ void setWarning(const QString &text) { m_label.setText(text); }
+ private:
+ QLabel &m_label;
+ };
+ WarningLabelSetter labelSetter(d->versionWarningLabel);
+
+ if (!d->clangdChooser.isValid())
+ return;
+ const Utils::FilePath clangdPath = d->clangdChooser.filePath();
+ Utils::QtcProcess clangdProc;
+ clangdProc.setCommand({clangdPath, {"--version"}});
+ clangdProc.start();
+ if (!clangdProc.waitForStarted() || !clangdProc.waitForFinished()) {
+ labelSetter.setWarning(tr("Failed to retrieve clangd version: %1")
+ .arg(clangdProc.exitMessage()));
+ return;
+ }
+ const QString output = clangdProc.allOutput();
+ static const QString versionPrefix = "clangd version ";
+ const int prefixOffset = output.indexOf(versionPrefix);
+ QVersionNumber clangdVersion;
+ if (prefixOffset != -1) {
+ clangdVersion = QVersionNumber::fromString(output.mid(prefixOffset
+ + versionPrefix.length()));
+ }
+ if (clangdVersion.isNull()) {
+ labelSetter.setWarning(tr("Failed to retrieve clangd version: "
+ "Unexpected clangd output."));
+ return;
+ }
+ if (clangdVersion < QVersionNumber(13)) {
+ labelSetter.setWarning(tr("The clangd version is %1, but %2 or greater is "
+ "recommended for full functionality.")
+ .arg(clangdVersion.toString()).arg(13));
+ return;
+ }
+ };
+ connect(&d->clangdChooser, &Utils::PathChooser::pathChanged, this, updateWarningLabel);
+ updateWarningLabel();
+
connect(&d->useClangdCheckBox, &QCheckBox::toggled,
this, &ClangdSettingsWidget::settingsDataChanged);
connect(&d->indexingCheckBox, &QCheckBox::toggled,
diff --git a/src/plugins/cppeditor/cppcompletionassist.cpp b/src/plugins/cppeditor/cppcompletionassist.cpp
index cd2c70b78c..ee04a15957 100644
--- a/src/plugins/cppeditor/cppcompletionassist.cpp
+++ b/src/plugins/cppeditor/cppcompletionassist.cpp
@@ -858,38 +858,8 @@ bool InternalCppCompletionAssistProcessor::accepts() const
if (pos - startOfName >= TextEditorSettings::completionSettings().m_characterThreshold) {
const QChar firstCharacter = m_interface->characterAt(startOfName);
if (isValidFirstIdentifierChar(firstCharacter)) {
- // Finally check that we're not inside a comment or string (code copied from startOfOperator)
- QTextCursor tc(m_interface->textDocument());
- tc.setPosition(pos);
-
- SimpleLexer tokenize;
- tokenize.setLanguageFeatures(m_interface->languageFeatures());
- tokenize.setSkipComments(false);
-
- const Tokens &tokens = tokenize(tc.block().text(), BackwardsScanner::previousBlockState(tc.block()));
- const int tokenIdx = SimpleLexer::tokenBefore(tokens, qMax(0, tc.positionInBlock() - 1));
- const Token tk = (tokenIdx == -1) ? Token() : tokens.at(tokenIdx);
-
- if (!tk.isComment() && !tk.isLiteral()) {
- return true;
- } else if (tk.isLiteral()
- && tokens.size() == 3
- && tokens.at(0).kind() == T_POUND
- && tokens.at(1).kind() == T_IDENTIFIER) {
- const QString &line = tc.block().text();
- const Token &idToken = tokens.at(1);
- QStringView identifier = idToken.utf16charsEnd() > line.size()
- ? QStringView(line).mid(
- idToken.utf16charsBegin())
- : QStringView(line)
- .mid(idToken.utf16charsBegin(),
- idToken.utf16chars());
- if (identifier == QLatin1String("include")
- || identifier == QLatin1String("include_next")
- || (m_interface->languageFeatures().objCEnabled && identifier == QLatin1String("import"))) {
- return true;
- }
- }
+ return !isInCommentOrString(m_interface.data(),
+ m_interface->languageFeatures());
}
}
}
diff --git a/src/plugins/cppeditor/cppfollowsymbolundercursor.cpp b/src/plugins/cppeditor/cppfollowsymbolundercursor.cpp
index ac2747cad7..11a3a70be0 100644
--- a/src/plugins/cppeditor/cppfollowsymbolundercursor.cpp
+++ b/src/plugins/cppeditor/cppfollowsymbolundercursor.cpp
@@ -417,17 +417,18 @@ bool maybeAppendArgumentOrParameterList(QString *expression, const QTextCursor &
bool isCursorOnTrailingReturnType(const QList<AST *> &astPath)
{
- for (auto it = astPath.cend() - 1, begin = astPath.cbegin(); it >= begin; --it) {
+ if (astPath.size() < 3)
+ return false;
+ for (auto it = astPath.cend() - 3, begin = astPath.cbegin(); it >= begin; --it) {
+ if (!(*it)->asTrailingReturnType())
+ continue;
const auto nextIt = it + 1;
const auto nextNextIt = nextIt + 1;
- if (nextNextIt != astPath.cend() && (*it)->asTrailingReturnType()) {
- return (*nextIt)->asNamedTypeSpecifier()
- && ((*nextNextIt)->asSimpleName()
- || (*nextNextIt)->asQualifiedName()
- || (*nextNextIt)->asTemplateId());
- }
+ return (*nextIt)->asNamedTypeSpecifier()
+ && ((*nextNextIt)->asSimpleName()
+ || (*nextNextIt)->asQualifiedName()
+ || (*nextNextIt)->asTemplateId());
}
-
return false;
}
diff --git a/src/plugins/cppeditor/cppmodelmanager.cpp b/src/plugins/cppeditor/cppmodelmanager.cpp
index 40b37263d8..4ddd690b42 100644
--- a/src/plugins/cppeditor/cppmodelmanager.cpp
+++ b/src/plugins/cppeditor/cppmodelmanager.cpp
@@ -694,6 +694,10 @@ CppModelManager::CppModelManager()
connect(KitManager::instance(), &KitManager::kitsChanged, this,
&CppModelManager::setupFallbackProjectPart);
+ connect(this, &CppModelManager::projectPartsRemoved, this,
+ &CppModelManager::setupFallbackProjectPart);
+ connect(this, &CppModelManager::projectPartsUpdated, this,
+ &CppModelManager::setupFallbackProjectPart);
setupFallbackProjectPart();
qRegisterMetaType<CPlusPlus::Document::Ptr>("CPlusPlus::Document::Ptr");
diff --git a/src/plugins/cppeditor/cppprojectfile.cpp b/src/plugins/cppeditor/cppprojectfile.cpp
index fa3bf8c023..58196521ca 100644
--- a/src/plugins/cppeditor/cppprojectfile.cpp
+++ b/src/plugins/cppeditor/cppprojectfile.cpp
@@ -87,6 +87,20 @@ bool ProjectFile::isAmbiguousHeader(const QString &filePath)
return filePath.endsWith(".h");
}
+bool ProjectFile::isObjC(const QString &filePath)
+{
+ const Kind kind = classify(filePath);
+ switch (kind) {
+ case CppEditor::ProjectFile::ObjCHeader:
+ case CppEditor::ProjectFile::ObjCXXHeader:
+ case CppEditor::ProjectFile::ObjCSource:
+ case CppEditor::ProjectFile::ObjCXXSource:
+ return true;
+ default:
+ return false;
+ }
+}
+
ProjectFile::Kind ProjectFile::sourceForHeaderKind(ProjectFile::Kind kind)
{
ProjectFile::Kind sourceKind;
diff --git a/src/plugins/cppeditor/cppprojectfile.h b/src/plugins/cppeditor/cppprojectfile.h
index 078b93cce9..1bd80fdf65 100644
--- a/src/plugins/cppeditor/cppprojectfile.h
+++ b/src/plugins/cppeditor/cppprojectfile.h
@@ -61,6 +61,7 @@ public:
static bool isC(Kind kind);
static bool isCxx(Kind kind);
static bool isAmbiguousHeader(const QString &filePath);
+ static bool isObjC(const QString &filePath);
bool isHeader() const;
bool isSource() const;
diff --git a/src/plugins/cppeditor/cppprojectupdater.h b/src/plugins/cppeditor/cppprojectupdater.h
index 165ec27910..b716ef3183 100644
--- a/src/plugins/cppeditor/cppprojectupdater.h
+++ b/src/plugins/cppeditor/cppprojectupdater.h
@@ -47,7 +47,7 @@ public:
CppProjectUpdaterFactory();
// keep the namespace, for the type name in the invokeMethod call
- Q_INVOKABLE CppProjectUpdaterInterface *create();
+ Q_INVOKABLE CppEditor::CppProjectUpdaterInterface *create();
};
} // namespace Internal
diff --git a/src/plugins/cppeditor/cppquickfixes.cpp b/src/plugins/cppeditor/cppquickfixes.cpp
index 8b9fdce190..91974761c2 100644
--- a/src/plugins/cppeditor/cppquickfixes.cpp
+++ b/src/plugins/cppeditor/cppquickfixes.cpp
@@ -2483,7 +2483,7 @@ void CompleteSwitchCaseStatement::match(const CppQuickFixInterface &interface,
AST *ast = path.at(depth);
SwitchStatementAST *switchStatement = ast->asSwitchStatement();
if (switchStatement) {
- if (!switchStatement->statement)
+ if (!switchStatement->statement || !switchStatement->symbol)
return;
CompoundStatementAST *compoundStatement = switchStatement->statement->asCompoundStatement();
if (!compoundStatement) // we ignore pathologic case "switch (t) case A: ;"
diff --git a/src/plugins/cppeditor/cpptoolsreuse.cpp b/src/plugins/cppeditor/cpptoolsreuse.cpp
index 15a1bea88a..04f679824a 100644
--- a/src/plugins/cppeditor/cpptoolsreuse.cpp
+++ b/src/plugins/cppeditor/cpptoolsreuse.cpp
@@ -39,11 +39,15 @@
#include <coreplugin/idocument.h>
#include <coreplugin/messagemanager.h>
#include <projectexplorer/session.h>
+#include <texteditor/codeassist/assistinterface.h>
#include <texteditor/textdocument.h>
-#include <cplusplus/Overview.h>
+#include <cplusplus/BackwardsScanner.h>
#include <cplusplus/LookupContext.h>
+#include <cplusplus/Overview.h>
+#include <cplusplus/SimpleLexer.h>
#include <utils/algorithm.h>
+#include <utils/porting.h>
#include <utils/textutils.h>
#include <utils/qtcassert.h>
@@ -300,6 +304,40 @@ const Macro *findCanonicalMacro(const QTextCursor &cursor, Document::Ptr documen
return nullptr;
}
+bool isInCommentOrString(const TextEditor::AssistInterface *interface,
+ CPlusPlus::LanguageFeatures features)
+{
+ QTextCursor tc(interface->textDocument());
+ tc.setPosition(interface->position());
+
+ SimpleLexer tokenize;
+ features.qtMocRunEnabled = true;
+ tokenize.setLanguageFeatures(features);
+ tokenize.setSkipComments(false);
+ const Tokens &tokens = tokenize(tc.block().text(),
+ BackwardsScanner::previousBlockState(tc.block()));
+ const int tokenIdx = SimpleLexer::tokenBefore(tokens, qMax(0, tc.positionInBlock() - 1));
+ const Token tk = (tokenIdx == -1) ? Token() : tokens.at(tokenIdx);
+
+ if (tk.isComment())
+ return true;
+ if (!tk.isLiteral())
+ return false;
+ if (tokens.size() == 3 && tokens.at(0).kind() == T_POUND
+ && tokens.at(1).kind() == T_IDENTIFIER) {
+ const QString &line = tc.block().text();
+ const Token &idToken = tokens.at(1);
+ QStringView identifier = Utils::midView(line, idToken.utf16charsBegin(),
+ idToken.utf16chars());
+ if (identifier == QLatin1String("include")
+ || identifier == QLatin1String("include_next")
+ || (features.objCEnabled && identifier == QLatin1String("import"))) {
+ return false;
+ }
+ }
+ return true;
+}
+
CppCodeModelSettings *codeModelSettings()
{
return Internal::CppEditorPlugin::instance()->codeModelSettings();
diff --git a/src/plugins/cppeditor/cpptoolsreuse.h b/src/plugins/cppeditor/cpptoolsreuse.h
index b3fd7a274b..e7023b7be7 100644
--- a/src/plugins/cppeditor/cpptoolsreuse.h
+++ b/src/plugins/cppeditor/cpptoolsreuse.h
@@ -35,6 +35,7 @@
#include <cplusplus/ASTVisitor.h>
#include <cplusplus/CppDocument.h>
+#include <cplusplus/Token.h>
QT_BEGIN_NAMESPACE
class QChar;
@@ -48,6 +49,8 @@ class Symbol;
class LookupContext;
} // namespace CPlusPlus
+namespace TextEditor { class AssistInterface; }
+
namespace CppEditor {
class CppRefactoringFile;
class ProjectInfo;
@@ -71,6 +74,9 @@ bool CPPEDITOR_EXPORT isOwnershipRAIIType(CPlusPlus::Symbol *symbol,
const CPlusPlus::Macro CPPEDITOR_EXPORT *findCanonicalMacro(const QTextCursor &cursor,
CPlusPlus::Document::Ptr document);
+bool CPPEDITOR_EXPORT isInCommentOrString(const TextEditor::AssistInterface *interface,
+ CPlusPlus::LanguageFeatures features);
+
enum class CacheUsage { ReadWrite, ReadOnly };
QString CPPEDITOR_EXPORT correspondingHeaderOrSource(const QString &fileName, bool *wasHeader = nullptr,
diff --git a/src/plugins/cppeditor/semantichighlighter.cpp b/src/plugins/cppeditor/semantichighlighter.cpp
index f3112a725b..eb6e90fb2b 100644
--- a/src/plugins/cppeditor/semantichighlighter.cpp
+++ b/src/plugins/cppeditor/semantichighlighter.cpp
@@ -180,6 +180,7 @@ void SemanticHighlighter::onHighlighterResultAvailable(int from, int to)
QPair<QTextBlock, Parentheses> parentheses;
for (int i = from; i < to; ++i) {
const HighlightingResult &result = m_watcher->future().resultAt(i);
+ QTC_ASSERT(result.line <= m_baseTextDocument->document()->blockCount(), continue);
if (result.kind != AngleBracketOpen && result.kind != AngleBracketClose
&& result.kind != DoubleAngleBracketClose
&& result.kind != TernaryIf && result.kind != TernaryElse) {
diff --git a/src/plugins/debugger/debuggerengine.cpp b/src/plugins/debugger/debuggerengine.cpp
index debdcaafdd..87d52ad74b 100644
--- a/src/plugins/debugger/debuggerengine.cpp
+++ b/src/plugins/debugger/debuggerengine.cpp
@@ -1891,7 +1891,7 @@ QString DebuggerEngine::nativeStartupCommands() const
return !trimmed.isEmpty() && !trimmed.startsWith('#');
});
- return lines.join('\n');
+ return expand(lines.join('\n'));
}
Perspective *DebuggerEngine::perspective() const
@@ -2827,7 +2827,7 @@ void CppDebuggerEngine::validateRunParameters(DebuggerRunParameters &rp)
globalRegExpSourceMap.reserve(sourcePathMap.size());
for (auto it = sourcePathMap.begin(), end = sourcePathMap.end(); it != end; ++it) {
if (it.key().startsWith('(')) {
- const QString expanded = Utils::globalMacroExpander()->expand(it.value());
+ const QString expanded = rp.macroExpander->expand(it.value());
if (!expanded.isEmpty())
globalRegExpSourceMap.push_back(
qMakePair(QRegularExpression(it.key()), expanded));
diff --git a/src/plugins/debugger/debuggerengine.h b/src/plugins/debugger/debuggerengine.h
index 8611e4668d..2099bc2f95 100644
--- a/src/plugins/debugger/debuggerengine.h
+++ b/src/plugins/debugger/debuggerengine.h
@@ -195,7 +195,7 @@ public:
bool isCppDebugging() const;
bool isNativeMixedDebugging() const;
- Utils::MacroExpander *macroExpander = nullptr;
+ const Utils::MacroExpander *macroExpander = nullptr;
Utils::optional<int> exitCode = {};
diff --git a/src/plugins/debugger/debuggeritem.cpp b/src/plugins/debugger/debuggeritem.cpp
index 36e066e09a..3a5060cbe5 100644
--- a/src/plugins/debugger/debuggeritem.cpp
+++ b/src/plugins/debugger/debuggeritem.cpp
@@ -225,7 +225,7 @@ void DebuggerItem::reinitializeFromFile(const Environment &sysEnv, QString *erro
return;
}
- qWarning() << "Unable to determine gdb target ABI";
+ qWarning() << "Unable to determine gdb target ABI via" << proc.commandLine().toUserOutput();
//! \note If unable to determine the GDB ABI, no ABI is appended to m_abis here.
return;
}
diff --git a/src/plugins/debugger/debuggerruncontrol.cpp b/src/plugins/debugger/debuggerruncontrol.cpp
index ffece20708..8b92c7d31d 100644
--- a/src/plugins/debugger/debuggerruncontrol.cpp
+++ b/src/plugins/debugger/debuggerruncontrol.cpp
@@ -885,7 +885,7 @@ DebuggerRunTool::DebuggerRunTool(RunControl *runControl, AllowTerminal allowTerm
QTC_ASSERT(kit, return);
m_runParameters.sysRoot = SysRootKitAspect::sysRoot(kit);
- m_runParameters.macroExpander = kit->macroExpander();
+ m_runParameters.macroExpander = runControl->macroExpander();
m_runParameters.debugger = DebuggerKitAspect::runnable(kit);
m_runParameters.cppEngineType = DebuggerKitAspect::engineType(kit);
diff --git a/src/plugins/debugger/gdb/gdbengine.cpp b/src/plugins/debugger/gdb/gdbengine.cpp
index 8109a3f91e..2251f4d9e6 100644
--- a/src/plugins/debugger/gdb/gdbengine.cpp
+++ b/src/plugins/debugger/gdb/gdbengine.cpp
@@ -3800,8 +3800,11 @@ static SourcePathMap mergeStartParametersSourcePathMap(const DebuggerRunParamete
{
// Do not overwrite user settings.
SourcePathMap rc = sp.sourcePathMap;
- for (auto it = in.constBegin(), end = in.constEnd(); it != end; ++it)
- rc.insert(it.key(), it.value());
+ for (auto it = in.constBegin(), end = in.constEnd(); it != end; ++it) {
+ // Entries that start with parenthesis are handled in CppDebuggerEngine::validateRunParameters
+ if (!it.key().startsWith('('))
+ rc.insert(it.key(), sp.macroExpander->expand(it.value()));
+ }
return rc;
}
@@ -3850,6 +3853,7 @@ void GdbEngine::setupEngine()
gdbCommand.addArg("-n");
Environment gdbEnv = rp.debugger.environment;
+ gdbEnv.setupEnglishOutput();
if (rp.runAsRoot) {
CommandLine wrapped("sudo", {"-A"});
wrapped.addCommandLineAsArgs(gdbCommand);
diff --git a/src/plugins/debugger/shared/cdbsymbolpathlisteditor.cpp b/src/plugins/debugger/shared/cdbsymbolpathlisteditor.cpp
index 18fcdce5dc..9ac3cee8ee 100644
--- a/src/plugins/debugger/shared/cdbsymbolpathlisteditor.cpp
+++ b/src/plugins/debugger/shared/cdbsymbolpathlisteditor.cpp
@@ -215,9 +215,9 @@ bool CdbSymbolPathListEditor::isSymbolServerPath(const QString &path, QString *c
if (!path.startsWith(QLatin1String(symbolServerPrefixC)) || !path.endsWith(QLatin1String(symbolServerPostfixC)))
return false;
if (cacheDir) {
- static const unsigned prefixLength = qstrlen(symbolServerPrefixC);
- static const unsigned postfixLength = qstrlen(symbolServerPostfixC);
- if (path.length() == int(prefixLength + postfixLength))
+ static const unsigned prefixLength = unsigned(qstrlen(symbolServerPrefixC));
+ static const unsigned postfixLength = unsigned(qstrlen(symbolServerPostfixC));
+ if (unsigned(path.length()) == prefixLength + postfixLength)
return true;
// Split apart symbol server post/prefixes
*cacheDir = path.mid(prefixLength, path.size() - prefixLength - qstrlen(symbolServerPostfixC) + 1);
@@ -230,7 +230,7 @@ bool CdbSymbolPathListEditor::isSymbolCachePath(const QString &path, QString *ca
if (!path.startsWith(QLatin1String(symbolCachePrefixC)))
return false;
if (cacheDir) {
- static const unsigned prefixLength = qstrlen(symbolCachePrefixC);
+ static const unsigned prefixLength = unsigned(qstrlen(symbolCachePrefixC));
// Split apart symbol cach prefixes
*cacheDir = path.mid(prefixLength);
}
diff --git a/src/plugins/debugger/watchhandler.cpp b/src/plugins/debugger/watchhandler.cpp
index 1dc061c508..20a5c95108 100644
--- a/src/plugins/debugger/watchhandler.cpp
+++ b/src/plugins/debugger/watchhandler.cpp
@@ -133,7 +133,7 @@ template <class T>
void readNumericVectorHelper(std::vector<double> *v, const QByteArray &ba)
{
const auto p = (const T*)ba.data();
- const int n = ba.size() / sizeof(T);
+ const int n = int(ba.size() / sizeof(T));
v->resize(n);
// Losing precision in case of 64 bit ints is ok here, as the result
// is only used to plot data.
diff --git a/src/plugins/designer/codemodelhelpers.cpp b/src/plugins/designer/codemodelhelpers.cpp
index b0d91f0a74..009bf83f53 100644
--- a/src/plugins/designer/codemodelhelpers.cpp
+++ b/src/plugins/designer/codemodelhelpers.cpp
@@ -82,7 +82,7 @@ private:
};
SearchFunction::SearchFunction(const char *name) :
- m_length(qstrlen(name)),
+ m_length(uint(qstrlen(name))),
m_name(name)
{
}
diff --git a/src/plugins/designer/formwindowfile.cpp b/src/plugins/designer/formwindowfile.cpp
index 5744256813..192a1383eb 100644
--- a/src/plugins/designer/formwindowfile.cpp
+++ b/src/plugins/designer/formwindowfile.cpp
@@ -247,6 +247,11 @@ QString FormWindowFile::fallbackSaveAsFileName() const
return m_suggestedName;
}
+bool FormWindowFile::supportsCodec(const QTextCodec *codec) const
+{
+ return codec == QTextCodec::codecForName("UTF-8");
+}
+
bool FormWindowFile::writeFile(const Utils::FilePath &filePath, QString *errorString) const
{
if (Designer::Constants::Internal::debug)
diff --git a/src/plugins/designer/formwindowfile.h b/src/plugins/designer/formwindowfile.h
index ca0ad50b3f..845a8ce0dc 100644
--- a/src/plugins/designer/formwindowfile.h
+++ b/src/plugins/designer/formwindowfile.h
@@ -58,6 +58,7 @@ public:
bool isSaveAsAllowed() const override;
bool reload(QString *errorString, ReloadFlag flag, ChangeType type) override;
QString fallbackSaveAsFileName() const override;
+ bool supportsCodec(const QTextCodec *codec) const override;
// Internal
void setFallbackSaveAsFileName(const QString &fileName);
diff --git a/src/plugins/docker/dockerdevice.cpp b/src/plugins/docker/dockerdevice.cpp
index 638fb91db0..4461c7a1e8 100644
--- a/src/plugins/docker/dockerdevice.cpp
+++ b/src/plugins/docker/dockerdevice.cpp
@@ -833,14 +833,7 @@ void DockerDevicePrivate::startContainer()
for (QString mount : qAsConst(m_data.mounts)) {
if (mount.isEmpty())
continue;
- // make sure to convert windows style paths to unix style paths with the file system case:
- // C:/dev/src -> /c/dev/src
- if (const FilePath mountPath = FilePath::fromUserInput(mount).normalizedPathName();
- mountPath.startsWithDriveLetter()) {
- const QChar lowerDriveLetter = mountPath.path().at(0).toLower();
- const FilePath path = FilePath::fromUserInput(mountPath.path().mid(2)); // strip C:
- mount = '/' + lowerDriveLetter + path.path();
- }
+ mount = q->mapToDevicePath(FilePath::fromUserInput(mount));
dockerCreate.addArgs({"-v", mount + ':' + mount});
}
@@ -1069,6 +1062,19 @@ FilePath DockerDevice::mapToGlobalPath(const FilePath &pathOnDevice) const
return result;
}
+QString DockerDevice::mapToDevicePath(const Utils::FilePath &globalPath) const
+{
+ // make sure to convert windows style paths to unix style paths with the file system case:
+ // C:/dev/src -> /c/dev/src
+ const FilePath normalized = FilePath::fromString(globalPath.path()).normalizedPathName();
+ QString path = normalized.path();
+ if (normalized.startsWithDriveLetter()) {
+ const QChar lowerDriveLetter = path.at(0).toLower();
+ path = '/' + lowerDriveLetter + path.mid(2); // strip C:
+ }
+ return path;
+}
+
bool DockerDevice::handlesFile(const FilePath &filePath) const
{
return filePath.scheme() == "docker" && filePath.host() == d->m_data.imageId;
@@ -1570,7 +1576,7 @@ void DockerDevice::runProcess(QtcProcess &process) const
CommandLine cmd{"docker", {"exec"}};
if (!workingDir.isEmpty()) {
- cmd.addArgs({"-w", workingDir.path()});
+ cmd.addArgs({"-w", mapToDevicePath(workingDir)});
if (QTC_GUARD(workingDir.needsDevice())) // warn on local working directory for docker cmd
process.setWorkingDirectory(FileUtils::homePath()); // reset working dir for docker exec
}
diff --git a/src/plugins/docker/dockerdevice.h b/src/plugins/docker/dockerdevice.h
index ded9a93b06..c4d0efe703 100644
--- a/src/plugins/docker/dockerdevice.h
+++ b/src/plugins/docker/dockerdevice.h
@@ -76,6 +76,7 @@ public:
ProjectExplorer::DeviceEnvironmentFetcher::Ptr environmentFetcher() const override;
Utils::FilePath mapToGlobalPath(const Utils::FilePath &pathOnDevice) const override;
+ QString mapToDevicePath(const Utils::FilePath &globalPath) const override;
bool handlesFile(const Utils::FilePath &filePath) const override;
bool isExecutableFile(const Utils::FilePath &filePath) const override;
diff --git a/src/plugins/fakevim/fakevimhandler.cpp b/src/plugins/fakevim/fakevimhandler.cpp
index 862dfc12b5..38ab02e0a9 100644
--- a/src/plugins/fakevim/fakevimhandler.cpp
+++ b/src/plugins/fakevim/fakevimhandler.cpp
@@ -1285,7 +1285,7 @@ public:
<< quoteUnprintable(m_text);
}
- friend uint qHash(const Input &i)
+ friend auto qHash(const Input &i)
{
return ::qHash(i.m_key);
}
@@ -6598,13 +6598,12 @@ bool FakeVimHandler::Private::handleExSourceCommand(const ExCommand &cmd)
while (!file.atEnd() || !line.isEmpty()) {
QByteArray nextline = !file.atEnd() ? file.readLine() : QByteArray();
- // remove comment
- int i = nextline.lastIndexOf('"');
- if (i != -1)
- nextline = nextline.remove(i, nextline.size() - i);
-
nextline = nextline.trimmed();
+ // remove full line comment. for being precise, check :help comment in vim.
+ if (nextline.startsWith('"'))
+ continue;
+
// multi-line command?
if (nextline.startsWith('\\')) {
line += nextline.mid(1);
@@ -8201,9 +8200,9 @@ void FakeVimHandler::Private::saveLastVisualMode()
if (isVisualMode() && g.mode == CommandMode && g.submode == NoSubMode) {
setMark('<', markLessPosition());
setMark('>', markGreaterPosition());
+ m_buffer->lastVisualModeInverted = anchor() > position();
+ m_buffer->lastVisualMode = g.visualMode;
}
- m_buffer->lastVisualModeInverted = anchor() > position();
- m_buffer->lastVisualMode = g.visualMode;
}
QWidget *FakeVimHandler::Private::editor() const
diff --git a/src/plugins/fakevim/fakevimplugin.cpp b/src/plugins/fakevim/fakevimplugin.cpp
index 8be735072d..fae4f7c835 100644
--- a/src/plugins/fakevim/fakevimplugin.cpp
+++ b/src/plugins/fakevim/fakevimplugin.cpp
@@ -380,7 +380,6 @@ private:
void copyTextEditorSettings();
void setQtStyle();
void setPlainStyle();
- void updateVimRcWidgets();
};
void FakeVimOptionPage::layoutPage(QWidget *widget)
@@ -449,15 +448,14 @@ void FakeVimOptionPage::layoutPage(QWidget *widget)
}.attachTo(widget, true);
+ s.vimRcPath.setEnabler(&s.readVimRc);
+
connect(copyTextEditorSettings, &QAbstractButton::clicked,
this, &FakeVimOptionPage::copyTextEditorSettings);
connect(setQtStyle, &QAbstractButton::clicked,
this, &FakeVimOptionPage::setQtStyle);
connect(setPlainStyle, &QAbstractButton::clicked,
this, &FakeVimOptionPage::setPlainStyle);
- connect(&s.readVimRc, &FvBaseAspect::changed,
- this, &FakeVimOptionPage::updateVimRcWidgets);
- updateVimRcWidgets();
}
void FakeVimOptionPage::copyTextEditorSettings()
@@ -503,13 +501,6 @@ void FakeVimOptionPage::setPlainStyle()
s.passKeys.setVolatileValue(false);
}
-void FakeVimOptionPage::updateVimRcWidgets()
-{
- FakeVimSettings &s = *fakeVimSettings();
- s.vimRcPath.setEnabled(s.readVimRc.value());
-}
-
-
///////////////////////////////////////////////////////////////////////
//
// FakeVimPluginPrivate
diff --git a/src/plugins/ios/iosprobe.cpp b/src/plugins/ios/iosprobe.cpp
index 79fddd3779..7fafba0ef4 100644
--- a/src/plugins/ios/iosprobe.cpp
+++ b/src/plugins/ios/iosprobe.cpp
@@ -160,12 +160,12 @@ bool XcodePlatform::operator==(const XcodePlatform &other) const
return developerPath == other.developerPath;
}
-uint qHash(const XcodePlatform &platform)
+Utils::QHashValueType qHash(const XcodePlatform &platform)
{
return qHash(platform.developerPath);
}
-uint qHash(const XcodePlatform::ToolchainTarget &target)
+Utils::QHashValueType qHash(const XcodePlatform::ToolchainTarget &target)
{
return qHash(target.name);
}
diff --git a/src/plugins/ios/iosprobe.h b/src/plugins/ios/iosprobe.h
index 52cf3015c5..966f669d08 100644
--- a/src/plugins/ios/iosprobe.h
+++ b/src/plugins/ios/iosprobe.h
@@ -24,6 +24,9 @@
****************************************************************************/
#pragma once
+
+#include <utils/porting.h>
+
#include <QSettings>
#include <QSharedPointer>
#include <QString>
@@ -61,8 +64,8 @@ public:
bool operator==(const XcodePlatform &other) const;
};
-uint qHash(const XcodePlatform &platform);
-uint qHash(const XcodePlatform::ToolchainTarget &target);
+Utils::QHashValueType qHash(const XcodePlatform &platform);
+Utils::QHashValueType qHash(const XcodePlatform::ToolchainTarget &target);
class XcodeProbe
{
diff --git a/src/plugins/languageclient/client.cpp b/src/plugins/languageclient/client.cpp
index 5f2b44d5e9..b177f82c52 100644
--- a/src/plugins/languageclient/client.cpp
+++ b/src/plugins/languageclient/client.cpp
@@ -1133,7 +1133,14 @@ void Client::handleMessage(const BaseMessage &message)
void Client::log(const QString &message) const
{
- Core::MessageManager::writeFlashing(QString("LanguageClient %1: %2").arg(name(), message));
+ switch (m_logTarget) {
+ case LogTarget::Ui:
+ Core::MessageManager::writeFlashing(QString("LanguageClient %1: %2").arg(name(), message));
+ break;
+ case LogTarget::Console:
+ qCDebug(LOGLSPCLIENT) << message;
+ break;
+ }
}
const ServerCapabilities &Client::capabilities() const
diff --git a/src/plugins/languageclient/client.h b/src/plugins/languageclient/client.h
index bf06359ef4..59f23599a4 100644
--- a/src/plugins/languageclient/client.h
+++ b/src/plugins/languageclient/client.h
@@ -189,6 +189,8 @@ public:
void setCompletionAssistProvider(LanguageClientCompletionAssistProvider *provider);
// logging
+ enum class LogTarget { Console, Ui };
+ void setLogTarget(LogTarget target) { m_logTarget = target; }
void log(const QString &message) const;
template<typename Error>
void log(const LanguageServerProtocol::ResponseError<Error> &responseError) const
@@ -288,6 +290,7 @@ private:
QString m_serverName;
QString m_serverVersion;
LanguageServerProtocol::SymbolStringifier m_symbolStringifier;
+ LogTarget m_logTarget = LogTarget::Ui;
bool m_locatorsEnabled = true;
bool m_autoRequestCodeActions = true;
};
diff --git a/src/plugins/languageclient/languageclientcompletionassist.cpp b/src/plugins/languageclient/languageclientcompletionassist.cpp
index ca38029dc1..3eec6cbbd9 100644
--- a/src/plugins/languageclient/languageclientcompletionassist.cpp
+++ b/src/plugins/languageclient/languageclientcompletionassist.cpp
@@ -425,7 +425,7 @@ void LanguageClientCompletionAssistProcessor::handleCompletionResponse(
items = Utils::get<QList<CompletionItem>>(*result);
}
auto proposalItems = generateCompletionItems(items);
- if (!m_snippetsGroup.isEmpty()) {
+ if (!proposalItems.isEmpty() && !m_snippetsGroup.isEmpty()) {
proposalItems << TextEditor::SnippetAssistCollector(
m_snippetsGroup, QIcon(":/texteditor/images/snippet.png")).collect();
}
diff --git a/src/plugins/modeleditor/modelindexer.cpp b/src/plugins/modeleditor/modelindexer.cpp
index be4e49d9cd..d05cf9ecb3 100644
--- a/src/plugins/modeleditor/modelindexer.cpp
+++ b/src/plugins/modeleditor/modelindexer.cpp
@@ -46,6 +46,7 @@
#include <utils/mimetypes/mimetype.h>
#include <utils/mimetypes/mimedatabase.h>
#include <utils/qtcassert.h>
+#include <utils/porting.h>
#include <QQueue>
#include <QMutex>
@@ -62,7 +63,7 @@ namespace Internal {
class ModelIndexer::QueuedFile
{
- friend uint qHash(const ModelIndexer::QueuedFile &queuedFile);
+ friend Utils::QHashValueType qHash(const ModelIndexer::QueuedFile &queuedFile);
friend bool operator==(const ModelIndexer::QueuedFile &lhs,
const ModelIndexer::QueuedFile &rhs);
@@ -99,7 +100,7 @@ bool operator==(const ModelIndexer::QueuedFile &lhs, const ModelIndexer::QueuedF
return lhs.m_file == rhs.m_file && lhs.m_project == rhs.m_project;
}
-uint qHash(const ModelIndexer::QueuedFile &queuedFile)
+Utils::QHashValueType qHash(const ModelIndexer::QueuedFile &queuedFile)
{
return qHash(queuedFile.m_project) + qHash(queuedFile.m_project);
}
diff --git a/src/plugins/modeleditor/modelindexer.h b/src/plugins/modeleditor/modelindexer.h
index 708ec26e9b..e6df8bdeed 100644
--- a/src/plugins/modeleditor/modelindexer.h
+++ b/src/plugins/modeleditor/modelindexer.h
@@ -25,6 +25,8 @@
#pragma once
+#include <utils/porting.h>
+
#include <QObject>
namespace qmt { class Uid; }
@@ -50,7 +52,7 @@ class ModelIndexer :
class DiagramsCollectorVisitor;
class ModelIndexerPrivate;
- friend uint qHash(const ModelIndexer::QueuedFile &queuedFile);
+ friend Utils::QHashValueType qHash(const ModelIndexer::QueuedFile &queuedFile);
friend bool operator==(const ModelIndexer::QueuedFile &lhs,
const ModelIndexer::QueuedFile &rhs);
diff --git a/src/plugins/perforce/perforceplugin.cpp b/src/plugins/perforce/perforceplugin.cpp
index be00bbf30c..16dd673959 100644
--- a/src/plugins/perforce/perforceplugin.cpp
+++ b/src/plugins/perforce/perforceplugin.cpp
@@ -36,6 +36,7 @@
#include <coreplugin/actionmanager/actioncontainer.h>
#include <coreplugin/actionmanager/command.h>
#include <coreplugin/coreconstants.h>
+#include <coreplugin/editormanager/documentmodel.h>
#include <coreplugin/editormanager/editormanager.h>
#include <coreplugin/documentmanager.h>
#include <coreplugin/icore.h>
@@ -1043,7 +1044,12 @@ bool PerforcePluginPrivate::vcsOpen(const FilePath &workingDir, const QString &f
flags |= SilentStdOut;
}
const PerforceResponse result = runP4Cmd(workingDir, args, flags);
- return !result.error;
+ if (result.error)
+ return false;
+ const FilePath absPath = workingDir.resolvePath(fileName);
+ if (DocumentModel::Entry *e = DocumentModel::entryForFilePath(absPath))
+ e->document->checkPermissions();
+ return true;
}
bool PerforcePluginPrivate::vcsAdd(const FilePath &workingDir, const QString &fileName)
diff --git a/src/plugins/projectexplorer/buildtargetinfo.h b/src/plugins/projectexplorer/buildtargetinfo.h
index 7d786de3ca..34d5f19624 100644
--- a/src/plugins/projectexplorer/buildtargetinfo.h
+++ b/src/plugins/projectexplorer/buildtargetinfo.h
@@ -30,6 +30,7 @@
#include <utils/algorithm.h>
#include <utils/environment.h>
#include <utils/fileutils.h>
+#include <utils/porting.h>
#include <QList>
@@ -48,7 +49,7 @@ public:
bool isQtcRunnable = true;
bool usesTerminal = false;
- uint runEnvModifierHash = 0; // Make sure to update this when runEnvModifier changes!
+ Utils::QHashValueType runEnvModifierHash = 0; // Make sure to update this when runEnvModifier changes!
std::function<void(Utils::Environment &, bool)> runEnvModifier;
};
diff --git a/src/plugins/projectexplorer/deployablefile.cpp b/src/plugins/projectexplorer/deployablefile.cpp
index 78fbcb165e..7ecfb59409 100644
--- a/src/plugins/projectexplorer/deployablefile.cpp
+++ b/src/plugins/projectexplorer/deployablefile.cpp
@@ -53,7 +53,7 @@ bool DeployableFile::isExecutable() const
return m_type == TypeExecutable;
}
-uint qHash(const DeployableFile &d)
+Utils::QHashValueType qHash(const DeployableFile &d)
{
return qHash(qMakePair(d.localFilePath().toString(), d.remoteDirectory()));
}
diff --git a/src/plugins/projectexplorer/deployablefile.h b/src/plugins/projectexplorer/deployablefile.h
index 4709206b16..e3760e4a02 100644
--- a/src/plugins/projectexplorer/deployablefile.h
+++ b/src/plugins/projectexplorer/deployablefile.h
@@ -28,6 +28,7 @@
#include "projectexplorer_export.h"
#include <utils/fileutils.h>
+#include <utils/porting.h>
#include <QString>
@@ -71,6 +72,6 @@ inline bool operator!=(const DeployableFile &d1, const DeployableFile &d2)
return !(d1 == d2);
}
-PROJECTEXPLORER_EXPORT uint qHash(const DeployableFile &d);
+PROJECTEXPLORER_EXPORT Utils::QHashValueType qHash(const DeployableFile &d);
} // namespace ProjectExplorer
diff --git a/src/plugins/projectexplorer/devicesupport/devicemanager.cpp b/src/plugins/projectexplorer/devicesupport/devicemanager.cpp
index f7470cd079..1e671e5fe3 100644
--- a/src/plugins/projectexplorer/devicesupport/devicemanager.cpp
+++ b/src/plugins/projectexplorer/devicesupport/devicemanager.cpp
@@ -484,6 +484,18 @@ DeviceManager::DeviceManager(bool isInstance) : d(std::make_unique<DeviceManager
return device->symLinkTarget(filePath);
};
+ deviceHooks.mapToGlobalPath = [](const FilePath &filePath) {
+ auto device = DeviceManager::deviceForPath(filePath);
+ QTC_ASSERT(device, return FilePath{});
+ return device->mapToGlobalPath(filePath);
+ };
+
+ deviceHooks.mapToDevicePath = [](const FilePath &filePath) {
+ auto device = DeviceManager::deviceForPath(filePath);
+ QTC_ASSERT(device, return QString{});
+ return device->mapToDevicePath(filePath);
+ };
+
deviceHooks.dirEntries = [](const FilePath &filePath, const QStringList &nameFilters,
QDir::Filters filters, QDir::SortFlags sort) {
auto device = DeviceManager::deviceForPath(filePath);
diff --git a/src/plugins/projectexplorer/devicesupport/idevice.cpp b/src/plugins/projectexplorer/devicesupport/idevice.cpp
index 8c90a7fc14..f1bedcc441 100644
--- a/src/plugins/projectexplorer/devicesupport/idevice.cpp
+++ b/src/plugins/projectexplorer/devicesupport/idevice.cpp
@@ -212,6 +212,11 @@ FilePath IDevice::mapToGlobalPath(const FilePath &pathOnDevice) const
return pathOnDevice;
}
+QString IDevice::mapToDevicePath(const FilePath &globalPath) const
+{
+ return globalPath.path();
+}
+
bool IDevice::handlesFile(const FilePath &filePath) const
{
Q_UNUSED(filePath);
diff --git a/src/plugins/projectexplorer/devicesupport/idevice.h b/src/plugins/projectexplorer/devicesupport/idevice.h
index 873eb380bb..56bdbb5bd2 100644
--- a/src/plugins/projectexplorer/devicesupport/idevice.h
+++ b/src/plugins/projectexplorer/devicesupport/idevice.h
@@ -237,6 +237,7 @@ public:
bool isAnyUnixDevice() const;
virtual Utils::FilePath mapToGlobalPath(const Utils::FilePath &pathOnDevice) const;
+ virtual QString mapToDevicePath(const Utils::FilePath &globalPath) const;
virtual bool handlesFile(const Utils::FilePath &filePath) const;
virtual bool isExecutableFile(const Utils::FilePath &filePath) const;
diff --git a/src/plugins/projectexplorer/expanddata.cpp b/src/plugins/projectexplorer/expanddata.cpp
index bf3876475d..4b005b8fe5 100644
--- a/src/plugins/projectexplorer/expanddata.cpp
+++ b/src/plugins/projectexplorer/expanddata.cpp
@@ -50,7 +50,7 @@ QVariant ExpandData::toSettings() const
return QVariant::fromValue(QStringList({path, displayName}));
}
-int ProjectExplorer::Internal::qHash(const ExpandData &data)
+Utils::QHashValueType ProjectExplorer::Internal::qHash(const ExpandData &data)
{
return qHash(data.path) ^ qHash(data.displayName);
}
diff --git a/src/plugins/projectexplorer/expanddata.h b/src/plugins/projectexplorer/expanddata.h
index 9d6a656449..a7ff078680 100644
--- a/src/plugins/projectexplorer/expanddata.h
+++ b/src/plugins/projectexplorer/expanddata.h
@@ -25,6 +25,8 @@
#pragma once
+#include <utils/porting.h>
+
#include <QString>
#include <QHash>
#include <QDebug>
@@ -46,7 +48,7 @@ public:
QString displayName;
};
-int qHash(const ExpandData &data);
+Utils::QHashValueType qHash(const ExpandData &data);
} // namespace Internal
} // namespace ProjectExplorer
diff --git a/src/plugins/projectexplorer/gccparser.cpp b/src/plugins/projectexplorer/gccparser.cpp
index 6479240c2b..30ebe45bf8 100644
--- a/src/plugins/projectexplorer/gccparser.cpp
+++ b/src/plugins/projectexplorer/gccparser.cpp
@@ -1367,6 +1367,14 @@ void ProjectExplorerPlugin::testGccOutputParsers_data()
CompileTask(Task::Error, ".pch/Qt6Core5Compat: No such file or directory", ".pch/Qt6Core5Compat"),
CompileTask(Task::Warning, "-Wformat-security ignored without -Wformat [-Wformat-security]")}
<< QString();
+
+ QTest::newRow("clean path")
+ << QString("/home/tim/path/to/sources/./and/more.h:15:22: error: blubb")
+ << OutputParserTester::STDERR
+ << QString() << QString()
+ << Tasks{CompileTask(Task::Error, "blubb", "/home/tim/path/to/sources/and/more.h",
+ 15, 22)}
+ << QString();
}
void ProjectExplorerPlugin::testGccOutputParsers()
diff --git a/src/plugins/projectexplorer/jsonwizard/jsonwizardfactory.cpp b/src/plugins/projectexplorer/jsonwizard/jsonwizardfactory.cpp
index ac73d2a047..31155c276c 100644
--- a/src/plugins/projectexplorer/jsonwizard/jsonwizardfactory.cpp
+++ b/src/plugins/projectexplorer/jsonwizard/jsonwizardfactory.cpp
@@ -87,6 +87,7 @@ const char PAGE_SHORT_TITLE_KEY[] = "trShortTitle";
const char PAGE_INDEX_KEY[] = "index";
const char OPTIONS_KEY[] = "options";
const char PLATFORM_INDEPENDENT_KEY[] = "platformIndependent";
+const char DEFAULT_VALUES[] = "defaultValues";
static QList<JsonWizardPageFactory *> s_pageFactories;
static QList<JsonWizardGeneratorFactory *> s_generatorFactories;
@@ -153,7 +154,131 @@ static JsonWizardFactory::Generator parseGenerator(const QVariant &value, QStrin
return gen;
}
-static JsonWizardFactory::Page parsePage(const QVariant &value, QString *errorMessage)
+//FIXME: createWizardFactories() has an almost identical loop. Make the loop return the results instead of
+//internal processing and create a separate function for it. Then process the results in
+//loadDefaultValues() and createWizardFactories()
+QVariantMap JsonWizardFactory::loadDefaultValues(const QString &fileName)
+{
+ QString verboseLog;
+
+ if (fileName.isEmpty()) {
+ return {};
+ }
+
+ QList <Core::IWizardFactory *> result;
+ foreach (const Utils::FilePath &path, searchPaths()) {
+ if (path.isEmpty())
+ continue;
+
+ FilePath dir = FilePath::fromString(path.toString());
+ if (!dir.exists()) {
+ if (verbose())
+ verboseLog.append(tr("Path \"%1\" does not exist when checking Json wizard search paths.\n")
+ .arg(path.toUserOutput()));
+ continue;
+ }
+
+ const QDir::Filters filters = QDir::Dirs|QDir::Readable|QDir::NoDotAndDotDot;
+ FilePaths dirs = dir.dirEntries(filters);
+
+ while (!dirs.isEmpty()) {
+ const FilePath current = dirs.takeFirst();
+ if (verbose())
+ verboseLog.append(tr("Checking \"%1\" for %2.\n")
+ .arg(QDir::toNativeSeparators(current.absolutePath().toString()))
+ .arg(fileName));
+ if (current.pathAppended(fileName).exists()) {
+ QFile configFile(current.pathAppended(fileName).toString());
+ configFile.open(QIODevice::ReadOnly);
+ QJsonParseError error;
+ const QByteArray fileData = configFile.readAll();
+ const QJsonDocument json = QJsonDocument::fromJson(fileData, &error);
+ configFile.close();
+
+ if (error.error != QJsonParseError::NoError) {
+ int line = 1;
+ int column = 1;
+ for (int i = 0; i < error.offset; ++i) {
+ if (fileData.at(i) == '\n') {
+ ++line;
+ column = 1;
+ } else {
+ ++column;
+ }
+ }
+ verboseLog.append(tr("* Failed to parse \"%1\":%2:%3: %4\n")
+ .arg(configFile.fileName())
+ .arg(line).arg(column)
+ .arg(error.errorString()));
+ continue;
+ }
+
+ if (!json.isObject()) {
+ verboseLog.append(tr("* Did not find a JSON object in \"%1\".\n")
+ .arg(configFile.fileName()));
+ continue;
+ }
+
+ if (verbose())
+ verboseLog.append(tr("* Configuration found and parsed.\n"));
+
+ return json.object().toVariantMap();
+ }
+ FilePaths subDirs = current.dirEntries(filters);
+ if (!subDirs.isEmpty()) {
+ // There is no QList::prepend(QList)...
+ dirs.swap(subDirs);
+ dirs.append(subDirs);
+ } else if (verbose()) {
+ verboseLog.append(tr("JsonWizard: \"%1\" not found\n").arg(fileName));
+ }
+ }
+ }
+
+ if (verbose()) { // Print to output pane for Windows.
+ qWarning("%s", qPrintable(verboseLog));
+ Core::MessageManager::writeDisrupting(verboseLog);
+ }
+
+ return {};
+}
+
+QVariant JsonWizardFactory::mergeDataValueMaps(const QVariant &valueMap, const QVariant &defaultValueMap)
+{
+ QVariantMap retVal;
+
+#if QT_VERSION < QT_VERSION_CHECK(5, 15, 0)
+ const QVariantMap &map = defaultValueMap.toMap();
+ for (auto it = map.begin(), end = map.end(); it != end; ++it)
+ retVal.insert(it.key(), it.value());
+
+ const QVariantMap &map2 = valueMap.toMap();
+ for (auto it = map2.begin(), end = map2.end(); it != end; ++it)
+ retVal.insert(it.key(), it.value());
+#else
+ retVal.insert(defaultValueMap.toMap());
+ retVal.insert(valueMap.toMap());
+#endif
+ return retVal;
+}
+
+QVariant JsonWizardFactory::getDataValue(const QLatin1String &key, const QVariantMap &valueSet,
+ const QVariantMap &defaultValueSet, const QVariant &notExistValue)
+{
+ QVariant retVal = {};
+
+ if ((valueSet.contains(key) && valueSet.value(key).type() == QVariant::Map) ||
+ (defaultValueSet.contains(key) && defaultValueSet.value(key).type() == QVariant::Map)) {
+ retVal = mergeDataValueMaps(valueSet.value(key), defaultValueSet.value(key));
+ } else {
+ QVariant defaultValue = defaultValueSet.value(key, notExistValue);
+ retVal = valueSet.value(key, defaultValue);
+ }
+
+ return retVal;
+}
+
+JsonWizardFactory::Page JsonWizardFactory::parsePage(const QVariant &value, QString *errorMessage)
{
JsonWizardFactory::Page p;
@@ -163,7 +288,12 @@ static JsonWizardFactory::Page parsePage(const QVariant &value, QString *errorMe
}
const QVariantMap data = value.toMap();
- const QString strVal = data.value(QLatin1String(TYPE_ID_KEY)).toString();
+ QString defaultValueFile = data.value(QLatin1String(DEFAULT_VALUES)).toString();
+ if (!defaultValueFile.isEmpty())
+ defaultValueFile.append(QLatin1String(".json"));
+ const QVariantMap defaultData = loadDefaultValues(defaultValueFile);
+
+ const QString strVal = getDataValue(QLatin1String(TYPE_ID_KEY), data, defaultData).toString();
if (strVal.isEmpty()) {
*errorMessage = QCoreApplication::translate("ProjectExplorer::JsonWizardFactory", "Page has no typeId set.");
return p;
@@ -180,21 +310,31 @@ static JsonWizardFactory::Page parsePage(const QVariant &value, QString *errorMe
return p;
}
- const QString title = JsonWizardFactory::localizedString(data.value(QLatin1String(DISPLAY_NAME_KEY)));
- const QString subTitle = JsonWizardFactory::localizedString(data.value(QLatin1String(PAGE_SUB_TITLE_KEY)));
- const QString shortTitle = JsonWizardFactory::localizedString(data.value(QLatin1String(PAGE_SHORT_TITLE_KEY)));
+ const QString title = JsonWizardFactory::localizedString(getDataValue(QLatin1String(DISPLAY_NAME_KEY), data, defaultData));
+ const QString subTitle = JsonWizardFactory::localizedString(getDataValue(QLatin1String(PAGE_SUB_TITLE_KEY), data, defaultData));
+ const QString shortTitle = JsonWizardFactory::localizedString(getDataValue(QLatin1String(PAGE_SHORT_TITLE_KEY), data, defaultData));
bool ok;
- int index = data.value(QLatin1String(PAGE_INDEX_KEY), -1).toInt(&ok);
+ int index = getDataValue(QLatin1String(PAGE_INDEX_KEY), data, defaultData, -1).toInt(&ok);
if (!ok) {
*errorMessage = QCoreApplication::translate("ProjectExplorer::JsonWizardFactory", "Page with typeId \"%1\" has invalid \"index\".")
.arg(typeId.toString());
return p;
}
- QVariant enabled = data.value(QLatin1String(ENABLED_EXPRESSION_KEY), true);
+ QVariant enabled = getDataValue(QLatin1String(ENABLED_EXPRESSION_KEY), data, defaultData, true);
+
+ QVariant specifiedSubData = data.value(QLatin1String(DATA_KEY));
+ QVariant defaultSubData = defaultData.value(QLatin1String(DATA_KEY));
+ QVariant subData;
+
+ if (specifiedSubData.isNull())
+ subData = defaultSubData;
+ else if (specifiedSubData.type() == QVariant::Map)
+ subData = mergeDataValueMaps(specifiedSubData.toMap(), defaultSubData.toMap());
+ else if (specifiedSubData.type() == QVariant::List)
+ subData = specifiedSubData;
- QVariant subData = data.value(QLatin1String(DATA_KEY));
if (!factory->validateData(typeId, subData, errorMessage))
return p;
@@ -209,6 +349,9 @@ static JsonWizardFactory::Page parsePage(const QVariant &value, QString *errorMe
return p;
}
+//FIXME: loadDefaultValues() has an almost identical loop. Make the loop return the results instead of
+//internal processing and create a separate function for it. Then process the results in
+//loadDefaultValues() and loadDefaultValues()
QList<Core::IWizardFactory *> JsonWizardFactory::createWizardFactories()
{
QString errorMessage;
@@ -258,14 +401,12 @@ QList<Core::IWizardFactory *> JsonWizardFactory::createWizardFactories()
.arg(currentFile.fileName())
.arg(line).arg(column)
.arg(error.errorString()));
- qWarning() << "Failed to parse wizard: " << currentFile.fileName();
continue;
}
if (!json.isObject()) {
verboseLog.append(tr("* Did not find a JSON object in \"%1\".\n")
.arg(currentFile.fileName()));
- qWarning() << "Failed to parse wizard: " << currentFile.fileName();
continue;
}
@@ -283,7 +424,6 @@ QList<Core::IWizardFactory *> JsonWizardFactory::createWizardFactories()
JsonWizardFactory *factory = createWizardFactory(data, currentDir, &errorMessage);
if (!factory) {
verboseLog.append(tr("* Failed to create: %1\n").arg(errorMessage));
- qWarning() << "Failed to create wizard: " << currentFile.fileName();
continue;
}
diff --git a/src/plugins/projectexplorer/jsonwizard/jsonwizardfactory.h b/src/plugins/projectexplorer/jsonwizard/jsonwizardfactory.h
index c3c6c5bd34..d69aaa00f0 100644
--- a/src/plugins/projectexplorer/jsonwizard/jsonwizardfactory.h
+++ b/src/plugins/projectexplorer/jsonwizard/jsonwizardfactory.h
@@ -100,6 +100,12 @@ private:
static void destroyAllFactories();
bool initialize(const QVariantMap &data, const Utils::FilePath &baseDir, QString *errorMessage);
+ JsonWizardFactory::Page parsePage(const QVariant &value, QString *errorMessage);
+ QVariantMap loadDefaultValues(const QString &fileName);
+ QVariant getDataValue(const QLatin1String &key, const QVariantMap &valueSet,
+ const QVariantMap &defaultValueSet, const QVariant &notExistValue={});
+ QVariant mergeDataValueMaps(const QVariant &valueMap, const QVariant &defaultValueMap);
+
QVariant m_enabledExpression;
Utils::FilePath m_wizardDir;
QList<Generator> m_generators;
diff --git a/src/plugins/projectexplorer/parseissuesdialog.cpp b/src/plugins/projectexplorer/parseissuesdialog.cpp
index 75be7e7bcb..f81db2da7d 100644
--- a/src/plugins/projectexplorer/parseissuesdialog.cpp
+++ b/src/plugins/projectexplorer/parseissuesdialog.cpp
@@ -32,9 +32,6 @@
#include "projectexplorerconstants.h"
#include "taskhub.h"
-#include <coreplugin/progressmanager/progressmanager.h>
-#include <utils/runextensions.h>
-
#include <QButtonGroup>
#include <QCheckBox>
#include <QDialogButtonBox>
@@ -137,21 +134,6 @@ ParseIssuesDialog::~ParseIssuesDialog()
delete d;
}
-static void parse(QFutureInterface<void> &future, const QString &output,
- const std::unique_ptr<Utils::OutputFormatter> &parser, bool isStderr)
-{
- const QStringList lines = output.split('\n');
- future.setProgressRange(0, lines.count());
- const Utils::OutputFormat format = isStderr ? Utils::StdErrFormat : Utils::StdOutFormat;
- for (const QString &line : lines) {
- parser->appendMessage(line + '\n', format);
- future.setProgressValue(future.progressValue() + 1);
- if (future.isCanceled())
- return;
- }
- parser->flush();
-}
-
void ParseIssuesDialog::accept()
{
const QList<Utils::OutputLineParser *> lineParsers =
@@ -161,14 +143,16 @@ void ParseIssuesDialog::accept()
"not provide an output parser."));
return;
}
- std::unique_ptr<Utils::OutputFormatter> parser(new Utils::OutputFormatter);
- parser->setLineParsers(lineParsers);
+ Utils::OutputFormatter parser;
+ parser.setLineParsers(lineParsers);
if (d->clearTasksCheckBox.isChecked())
TaskHub::clearTasks();
- const QFuture<void> f = Utils::runAsync(&parse, d->compileOutputEdit.toPlainText(),
- std::move(parser), d->stderrCheckBox.isChecked());
- Core::ProgressManager::addTask(f, tr("Parsing build output"),
- "ProgressExplorer.ParseExternalBuildOutput");
+ const QStringList lines = d->compileOutputEdit.toPlainText().split('\n');
+ const Utils::OutputFormat format = d->stderrCheckBox.isChecked()
+ ? Utils::StdErrFormat : Utils::StdOutFormat;
+ for (const QString &line : lines)
+ parser.appendMessage(line + '\n', format);
+ parser.flush();
QDialog::accept();
}
diff --git a/src/plugins/projectexplorer/project.cpp b/src/plugins/projectexplorer/project.cpp
index a49011bc41..b283862c46 100644
--- a/src/plugins/projectexplorer/project.cpp
+++ b/src/plugins/projectexplorer/project.cpp
@@ -376,7 +376,7 @@ void Project::setExtraProjectFiles(const QSet<FilePath> &projectDocumentPaths,
const QSet<FilePath> toAdd = uniqueNewFiles - existingWatches;
const QSet<FilePath> toRemove = existingWatches - uniqueNewFiles;
- erase(d->m_extraProjectDocuments, [&toRemove](const std::unique_ptr<IDocument> &d) {
+ Utils::erase(d->m_extraProjectDocuments, [&toRemove](const std::unique_ptr<IDocument> &d) {
return toRemove.contains(d->filePath());
});
if (docUpdater) {
@@ -586,7 +586,8 @@ void Project::setRootProjectNode(std::unique_ptr<ProjectNode> &&root)
}
if (root) {
- ProjectTree::applyTreeManager(root.get());
+ ProjectTree::applyTreeManager(root.get(), ProjectTree::AsyncPhase);
+ ProjectTree::applyTreeManager(root.get(), ProjectTree::FinalPhase);
root->setParentFolderNode(d->m_containerNode.get());
}
@@ -804,8 +805,9 @@ void Project::createTargetFromMap(const QVariantMap &map, int index)
deviceTypeId = Constants::DESKTOP_DEVICE_TYPE;
const QString formerKitName = targetMap.value(Target::displayNameKey()).toString();
k = KitManager::registerKit([deviceTypeId, &formerKitName](Kit *kit) {
- const QString tempKitName = makeUniquelyNumbered(
- tr("Replacement for \"%1\"").arg(formerKitName),
+ const QString kitNameSuggestion = formerKitName.contains(tr("Replacement for"))
+ ? formerKitName : tr("Replacement for \"%1\"").arg(formerKitName);
+ const QString tempKitName = makeUniquelyNumbered(kitNameSuggestion,
transform(KitManager::kits(), &Kit::unexpandedDisplayName));
kit->setUnexpandedDisplayName(tempKitName);
DeviceTypeKitAspect::setDeviceTypeId(kit, deviceTypeId);
diff --git a/src/plugins/projectexplorer/projectexplorer.cpp b/src/plugins/projectexplorer/projectexplorer.cpp
index f7fe67d213..46db91993a 100644
--- a/src/plugins/projectexplorer/projectexplorer.cpp
+++ b/src/plugins/projectexplorer/projectexplorer.cpp
@@ -2602,7 +2602,7 @@ void ProjectExplorerPluginPrivate::restoreSession()
dd->m_arguments = arguments;
// delay opening projects from the command line even more
QTimer::singleShot(0, m_instance, []() {
- ICore::openFiles(Utils::transform(dd->m_arguments, &FilePath::fromString),
+ ICore::openFiles(Utils::transform(dd->m_arguments, &FilePath::fromUserInput),
ICore::OpenFilesFlags(ICore::CanContainLineAndColumnNumbers | ICore::SwitchMode));
emit m_instance->finishedInitialization();
});
diff --git a/src/plugins/projectexplorer/projecttree.cpp b/src/plugins/projectexplorer/projecttree.cpp
index aa8e79f9ef..ee040d5a37 100644
--- a/src/plugins/projectexplorer/projecttree.cpp
+++ b/src/plugins/projectexplorer/projecttree.cpp
@@ -402,13 +402,13 @@ void ProjectTree::registerTreeManager(const TreeManagerFunction &treeChange)
s_instance->m_treeManagers.append(treeChange);
}
-void ProjectTree::applyTreeManager(FolderNode *folder)
+void ProjectTree::applyTreeManager(FolderNode *folder, ConstructionPhase phase)
{
if (!folder)
return;
for (TreeManagerFunction &f : s_instance->m_treeManagers)
- f(folder);
+ f(folder, phase);
}
bool ProjectTree::hasNode(const Node *node)
diff --git a/src/plugins/projectexplorer/projecttree.h b/src/plugins/projectexplorer/projecttree.h
index 060dad2290..3947666d3a 100644
--- a/src/plugins/projectexplorer/projecttree.h
+++ b/src/plugins/projectexplorer/projecttree.h
@@ -68,6 +68,11 @@ public:
const bool m_active = false;
};
+ enum ConstructionPhase {
+ AsyncPhase,
+ FinalPhase
+ };
+
// Integration with ProjectTreeWidget
static void registerWidget(Internal::ProjectTreeWidget *widget);
static void unregisterWidget(Internal::ProjectTreeWidget *widget);
@@ -79,9 +84,9 @@ public:
static void highlightProject(Project *project, const QString &message);
- using TreeManagerFunction = std::function<void(FolderNode *)>;
+ using TreeManagerFunction = std::function<void(FolderNode *, ConstructionPhase)>;
static void registerTreeManager(const TreeManagerFunction &treeChange);
- static void applyTreeManager(FolderNode *folder);
+ static void applyTreeManager(FolderNode *folder, ConstructionPhase phase);
// Nodes:
static bool hasNode(const Node *node);
diff --git a/src/plugins/projectexplorer/runconfigurationaspects.cpp b/src/plugins/projectexplorer/runconfigurationaspects.cpp
index 0a3a2634b0..2291a86fbd 100644
--- a/src/plugins/projectexplorer/runconfigurationaspects.cpp
+++ b/src/plugins/projectexplorer/runconfigurationaspects.cpp
@@ -251,7 +251,9 @@ FilePath WorkingDirectoryAspect::workingDirectory() const
const Environment env = m_envAspect ? m_envAspect->environment()
: Environment::systemEnvironment();
FilePath res = m_workingDirectory;
- const QString workingDir = m_workingDirectory.path();
+ QString workingDir = m_workingDirectory.path();
+ if (m_macroExpander)
+ workingDir = m_macroExpander->expandProcessArgs(workingDir);
res.setPath(PathChooser::expandedDirectory(workingDir, env, QString()));
return res;
}
diff --git a/src/plugins/projectexplorer/runcontrol.cpp b/src/plugins/projectexplorer/runcontrol.cpp
index 4cd0665f09..9ca0e228c3 100644
--- a/src/plugins/projectexplorer/runcontrol.cpp
+++ b/src/plugins/projectexplorer/runcontrol.cpp
@@ -349,7 +349,7 @@ public:
IDevice::ConstPtr device;
Utils::Id runMode;
Utils::Icon icon;
- const MacroExpander *macroExpander;
+ const MacroExpander *macroExpander = nullptr;
QPointer<RunConfiguration> runConfiguration; // Not owned. Avoid use.
QString buildKey;
QMap<Utils::Id, QVariantMap> settingsData;
@@ -389,11 +389,12 @@ void RunControl::setRunConfiguration(RunConfiguration *runConfig)
d->runConfigId = runConfig->id();
d->runnable = runConfig->runnable();
d->displayName = runConfig->expandedDisplayName();
- d->macroExpander = runConfig->macroExpander();
d->buildKey = runConfig->buildKey();
d->settingsData = runConfig->aspectData();
setTarget(runConfig->target());
+
+ d->macroExpander = runConfig->macroExpander();
}
void RunControl::setTarget(Target *target)
@@ -412,6 +413,7 @@ void RunControl::setTarget(Target *target)
}
setKit(target->kit());
+ d->macroExpander = target->macroExpander();
d->project = target->project();
}
@@ -420,6 +422,7 @@ void RunControl::setKit(Kit *kit)
QTC_ASSERT(kit, return);
QTC_CHECK(!d->kit);
d->kit = kit;
+ d->macroExpander = kit->macroExpander();
if (d->runnable.device)
setDevice(d->runnable.device);
diff --git a/src/plugins/projectexplorer/task.cpp b/src/plugins/projectexplorer/task.cpp
index fe880442ba..3ef9e397a9 100644
--- a/src/plugins/projectexplorer/task.cpp
+++ b/src/plugins/projectexplorer/task.cpp
@@ -171,7 +171,7 @@ bool operator<(const Task &a, const Task &b)
}
-uint qHash(const Task &task)
+Utils::QHashValueType qHash(const Task &task)
{
return task.taskId;
}
diff --git a/src/plugins/projectexplorer/task.h b/src/plugins/projectexplorer/task.h
index a21332c708..b95d51d34e 100644
--- a/src/plugins/projectexplorer/task.h
+++ b/src/plugins/projectexplorer/task.h
@@ -29,6 +29,7 @@
#include <utils/id.h>
#include <utils/fileutils.h>
+#include <utils/porting.h>
#include <QIcon>
#include <QMetaType>
@@ -135,13 +136,13 @@ public:
using Tasks = QVector<Task>;
-bool PROJECTEXPLORER_EXPORT operator==(const Task &t1, const Task &t2);
-uint PROJECTEXPLORER_EXPORT qHash(const Task &task);
+PROJECTEXPLORER_EXPORT bool operator==(const Task &t1, const Task &t2);
+PROJECTEXPLORER_EXPORT Utils::QHashValueType qHash(const Task &task);
-bool PROJECTEXPLORER_EXPORT operator<(const Task &a, const Task &b);
+PROJECTEXPLORER_EXPORT bool operator<(const Task &a, const Task &b);
-QString PROJECTEXPLORER_EXPORT toHtml(const Tasks &issues);
-bool PROJECTEXPLORER_EXPORT containsType(const Tasks &issues, Task::TaskType);
+PROJECTEXPLORER_EXPORT QString toHtml(const Tasks &issues);
+PROJECTEXPLORER_EXPORT bool containsType(const Tasks &issues, Task::TaskType);
} //namespace ProjectExplorer
diff --git a/src/plugins/projectexplorer/treescanner.cpp b/src/plugins/projectexplorer/treescanner.cpp
index ce6da40b1c..88e7b8d4a8 100644
--- a/src/plugins/projectexplorer/treescanner.cpp
+++ b/src/plugins/projectexplorer/treescanner.cpp
@@ -159,7 +159,7 @@ static std::unique_ptr<FolderNode> createFolderNode(const Utils::FilePath &direc
std::unique_ptr<FileNode> node(fn->clone());
fileSystemNode->addNestedNode(std::move(node));
}
- ProjectTree::applyTreeManager(fileSystemNode.get()); // QRC nodes
+ ProjectTree::applyTreeManager(fileSystemNode.get(), ProjectTree::AsyncPhase); // QRC nodes
return fileSystemNode;
}
diff --git a/src/plugins/qbsprojectmanager/qbsnodetreebuilder.cpp b/src/plugins/qbsprojectmanager/qbsnodetreebuilder.cpp
index c481975753..7e3c31c378 100644
--- a/src/plugins/qbsprojectmanager/qbsnodetreebuilder.cpp
+++ b/src/plugins/qbsprojectmanager/qbsnodetreebuilder.cpp
@@ -232,7 +232,7 @@ QbsProjectNode *QbsNodeTreeBuilder::buildTree(const QString &projectName,
}
buildSystemFiles->compress();
root->addNode(std::move(buildSystemFiles));
- ProjectTree::applyTreeManager(root.get()); // QRC nodes
+ ProjectTree::applyTreeManager(root.get(), ProjectTree::AsyncPhase); // QRC nodes
return root.release();
}
diff --git a/src/plugins/qmakeprojectmanager/qmakeparsernodes.cpp b/src/plugins/qmakeprojectmanager/qmakeparsernodes.cpp
index f64aecd296..b9c048764e 100644
--- a/src/plugins/qmakeprojectmanager/qmakeparsernodes.cpp
+++ b/src/plugins/qmakeprojectmanager/qmakeparsernodes.cpp
@@ -69,8 +69,8 @@ namespace QmakeProjectManager {
static Q_LOGGING_CATEGORY(qmakeParse, "qtc.qmake.parsing", QtWarningMsg);
-uint qHash(Variable key, uint seed) { return ::qHash(static_cast<int>(key), seed); }
-uint qHash(FileOrigin fo) { return ::qHash(int(fo)); }
+Utils::QHashValueType qHash(Variable key, uint seed) { return ::qHash(static_cast<int>(key), seed); }
+Utils::QHashValueType qHash(FileOrigin fo) { return ::qHash(int(fo)); }
namespace Internal {
diff --git a/src/plugins/qmakeprojectmanager/qmakeparsernodes.h b/src/plugins/qmakeprojectmanager/qmakeparsernodes.h
index cfa86b181f..9a4a22690e 100644
--- a/src/plugins/qmakeprojectmanager/qmakeparsernodes.h
+++ b/src/plugins/qmakeprojectmanager/qmakeparsernodes.h
@@ -31,6 +31,7 @@
#include <coreplugin/idocument.h>
#include <cppeditor/generatedcodemodelsupport.h>
+#include <utils/porting.h>
#include <utils/textfileformat.h>
#include <QFutureWatcher>
@@ -109,7 +110,7 @@ enum class Variable {
QmakeCc,
QmakeCxx
};
-uint qHash(Variable key, uint seed = 0);
+Utils::QHashValueType qHash(Variable key, uint seed = 0);
namespace Internal {
Q_DECLARE_LOGGING_CATEGORY(qmakeNodesLog)
@@ -121,7 +122,7 @@ class QmakePriFileEvalResult;
class InstallsList;
enum class FileOrigin { ExactParse, CumulativeParse };
-uint qHash(FileOrigin fo);
+Utils::QHashValueType qHash(FileOrigin fo);
using SourceFile = QPair<Utils::FilePath, FileOrigin>;
using SourceFiles = QSet<SourceFile>;
diff --git a/src/plugins/qmldesigner/CMakeLists.txt b/src/plugins/qmldesigner/CMakeLists.txt
index ce73af5161..0fe3867a7e 100644
--- a/src/plugins/qmldesigner/CMakeLists.txt
+++ b/src/plugins/qmldesigner/CMakeLists.txt
@@ -4,6 +4,7 @@ if (APPLE)
endif()
add_qtc_plugin(QmlDesigner
+ CONDITION TARGET Qt5::QuickWidgets
DEPENDS
QmlJS LanguageUtils QmlEditorWidgets AdvancedDockingSystem
Qt5::QuickWidgets Qt5::CorePrivate Sqlite
@@ -27,6 +28,7 @@ add_qtc_plugin(QmlDesigner
documentmanager.cpp documentmanager.h
documentwarningwidget.cpp documentwarningwidget.h
generateresource.cpp generateresource.h
+ generatecmakelists.cpp generatecmakelists.h
openuiqmlfiledialog.cpp openuiqmlfiledialog.h openuiqmlfiledialog.ui
qmldesignerconstants.h
qmldesignericons.h
diff --git a/src/plugins/qmldesigner/components/bindingeditor/abstracteditordialog.cpp b/src/plugins/qmldesigner/components/bindingeditor/abstracteditordialog.cpp
index 872a004fcc..5b8a4934dd 100644
--- a/src/plugins/qmldesigner/components/bindingeditor/abstracteditordialog.cpp
+++ b/src/plugins/qmldesigner/components/bindingeditor/abstracteditordialog.cpp
@@ -46,7 +46,7 @@ AbstractEditorDialog::AbstractEditorDialog(QWidget *parent, const QString &title
{
setWindowFlag(Qt::Tool, true);
setWindowTitle(defaultTitle());
- setModal(false);
+ setModal(true);
setupJSEditor();
setupUIComponents();
@@ -111,11 +111,10 @@ void AbstractEditorDialog::setupJSEditor()
{
static BindingEditorFactory f;
m_editor = qobject_cast<TextEditor::BaseTextEditor*>(f.createEditor());
- m_editorWidget = qobject_cast<BindingEditorWidget*>(m_editor->editorWidget());
+ Q_ASSERT(m_editor);
- Core::Context context = m_editor->context();
- context.prepend(BINDINGEDITOR_CONTEXT_ID);
- m_editorWidget->m_context->setContext(context);
+ m_editorWidget = qobject_cast<BindingEditorWidget*>(m_editor->editorWidget());
+ Q_ASSERT(m_editorWidget);
auto qmlDesignerEditor = QmlDesignerPlugin::instance()->currentDesignDocument()->textEditor();
diff --git a/src/plugins/qmldesigner/components/bindingeditor/abstracteditordialog.h b/src/plugins/qmldesigner/components/bindingeditor/abstracteditordialog.h
index ed8cdd0a13..76de79b195 100644
--- a/src/plugins/qmldesigner/components/bindingeditor/abstracteditordialog.h
+++ b/src/plugins/qmldesigner/components/bindingeditor/abstracteditordialog.h
@@ -26,9 +26,10 @@
#ifndef ABSTRACTEDITORDIALOG_H
#define ABSTRACTEDITORDIALOG_H
-#include <bindingeditor/bindingeditorwidget.h>
#include <qmldesignercorelib_global.h>
+
#include <texteditor/texteditor.h>
+#include <bindingeditor/bindingeditorwidget.h>
#include <QDialog>
diff --git a/src/plugins/qmldesigner/components/bindingeditor/actioneditor.cpp b/src/plugins/qmldesigner/components/bindingeditor/actioneditor.cpp
index 89364c5116..1f2a8224d3 100644
--- a/src/plugins/qmldesigner/components/bindingeditor/actioneditor.cpp
+++ b/src/plugins/qmldesigner/components/bindingeditor/actioneditor.cpp
@@ -286,10 +286,13 @@ void ActionEditor::prepareConnections()
m_dialog->setAllConnections(connections, singletons, states);
}
-void ActionEditor::updateWindowName()
+void ActionEditor::updateWindowName(const QString &targetName)
{
if (!m_dialog.isNull()) {
- m_dialog->setWindowTitle(m_dialog->defaultTitle());
+ if (targetName.isEmpty())
+ m_dialog->setWindowTitle(m_dialog->defaultTitle());
+ else
+ m_dialog->setWindowTitle(m_dialog->defaultTitle() + " [" + targetName + "]");
m_dialog->raise();
}
}
diff --git a/src/plugins/qmldesigner/components/bindingeditor/actioneditor.h b/src/plugins/qmldesigner/components/bindingeditor/actioneditor.h
index c0356e81c4..09597bc8d1 100644
--- a/src/plugins/qmldesigner/components/bindingeditor/actioneditor.h
+++ b/src/plugins/qmldesigner/components/bindingeditor/actioneditor.h
@@ -64,7 +64,7 @@ public:
void prepareConnections();
- Q_INVOKABLE void updateWindowName();
+ Q_INVOKABLE void updateWindowName(const QString &targetName = {});
signals:
void accepted();
diff --git a/src/plugins/qmldesigner/components/bindingeditor/bindingeditor.cpp b/src/plugins/qmldesigner/components/bindingeditor/bindingeditor.cpp
index d28457e1f5..eff90366a0 100644
--- a/src/plugins/qmldesigner/components/bindingeditor/bindingeditor.cpp
+++ b/src/plugins/qmldesigner/components/bindingeditor/bindingeditor.cpp
@@ -42,8 +42,6 @@
namespace QmlDesigner {
-static BindingEditor *s_lastBindingEditor = nullptr;
-
BindingEditor::BindingEditor(QObject *)
{
}
@@ -62,11 +60,6 @@ void BindingEditor::prepareDialog()
{
QmlDesignerPlugin::emitUsageStatistics(Constants::EVENT_BINDINGEDITOR_OPENED);
- if (s_lastBindingEditor)
- s_lastBindingEditor->hideWidget();
-
- s_lastBindingEditor = this;
-
m_dialog = new BindingEditorDialog(Core::ICore::dialogParent());
QObject::connect(m_dialog, &AbstractEditorDialog::accepted,
@@ -91,9 +84,6 @@ void BindingEditor::showWidget(int x, int y)
void BindingEditor::hideWidget()
{
- if (s_lastBindingEditor == this)
- s_lastBindingEditor = nullptr;
-
if (m_dialog) {
m_dialog->unregisterAutoCompletion(); //we have to do it separately, otherwise we have an autocompletion action override
m_dialog->close();
@@ -125,6 +115,12 @@ void BindingEditor::setBackendValue(const QVariant &backendValue)
if (node.isValid()) {
m_backendValueTypeName = node.metaInfo().propertyTypeName(propertyEditorValue->name());
+ QString nodeId = node.id();
+ if (nodeId.isEmpty())
+ nodeId = node.simplifiedTypeName();
+
+ m_targetName = nodeId + "." + propertyEditorValue->name();
+
if (m_backendValueTypeName == "alias" || m_backendValueTypeName == "unknown")
if (QmlObjectNode::isValidQmlObjectNode(node))
m_backendValueTypeName = QmlObjectNode(node).instanceType(propertyEditorValue->name());
@@ -164,6 +160,12 @@ void BindingEditor::setStateModelNode(const QVariant &stateModelNode)
}
}
+void BindingEditor::setStateName(const QString &name)
+{
+ m_targetName = name;
+ m_targetName += ".when";
+}
+
void BindingEditor::setModelNode(const ModelNode &modelNode)
{
if (modelNode.isValid())
@@ -177,6 +179,11 @@ void BindingEditor::setBackendValueTypeName(const TypeName &backendValueTypeName
emit backendValueChanged();
}
+void BindingEditor::setTargetName(const QString &target)
+{
+ m_targetName = target;
+}
+
void BindingEditor::prepareBindings()
{
if (!m_modelNode.isValid() || m_backendValueTypeName.isEmpty())
@@ -279,8 +286,26 @@ void BindingEditor::prepareBindings()
void BindingEditor::updateWindowName()
{
- if (!m_dialog.isNull() && !m_backendValueTypeName.isEmpty())
- m_dialog->setWindowTitle(m_dialog->defaultTitle() + " [" + m_backendValueTypeName + "]");
+ if (!m_dialog.isNull() && !m_backendValueTypeName.isEmpty()) {
+ const QString targetString = " ["
+ + (m_targetName.isEmpty() ? QString() : (m_targetName + ": "))
+ + QString::fromUtf8(m_backendValueTypeName) + "]";
+
+ m_dialog->setWindowTitle(m_dialog->defaultTitle() + targetString);
+ }
+}
+
+QString BindingEditor::targetName() const
+{
+ return m_targetName;
+}
+
+QString BindingEditor::stateName() const
+{
+ if (m_targetName.endsWith(".when"))
+ return m_targetName.chopped(5);
+
+ return {};
}
QVariant BindingEditor::backendValue() const
diff --git a/src/plugins/qmldesigner/components/bindingeditor/bindingeditor.h b/src/plugins/qmldesigner/components/bindingeditor/bindingeditor.h
index 495462128f..738d9c7101 100644
--- a/src/plugins/qmldesigner/components/bindingeditor/bindingeditor.h
+++ b/src/plugins/qmldesigner/components/bindingeditor/bindingeditor.h
@@ -44,6 +44,7 @@ class BindingEditor : public QObject
Q_PROPERTY(QVariant backendValueProperty READ backendValue WRITE setBackendValue NOTIFY backendValueChanged)
Q_PROPERTY(QVariant modelNodeBackendProperty READ modelNodeBackend WRITE setModelNodeBackend NOTIFY modelNodeBackendChanged)
Q_PROPERTY(QVariant stateModelNodeProperty READ stateModelNode WRITE setStateModelNode NOTIFY stateModelNodeChanged)
+ Q_PROPERTY(QString stateNameProperty READ stateName WRITE setStateName)
public:
BindingEditor(QObject *parent = nullptr);
@@ -64,15 +65,21 @@ public:
void setModelNodeBackend(const QVariant &modelNodeBackend);
//2. modelnode (this one also sets backend value type name to bool)
+ //State Name is not mandatory, but used in bindingEditor dialog name
void setStateModelNode(const QVariant &stateModelNode);
+ void setStateName(const QString &name);
- //3. modelnode + backend value type name
+ //3. modelnode + backend value type name + optional target name
void setModelNode(const ModelNode &modelNode);
void setBackendValueTypeName(const TypeName &backendValueTypeName);
+ void setTargetName(const QString &target);
Q_INVOKABLE void prepareBindings();
Q_INVOKABLE void updateWindowName();
+ QString targetName() const;
+ QString stateName() const;
+
signals:
void accepted();
void rejected();
@@ -93,6 +100,7 @@ private:
QVariant m_stateModelNode;
QmlDesigner::ModelNode m_modelNode;
TypeName m_backendValueTypeName;
+ QString m_targetName;
};
}
diff --git a/src/plugins/qmldesigner/components/bindingeditor/bindingeditorwidget.cpp b/src/plugins/qmldesigner/components/bindingeditor/bindingeditorwidget.cpp
index 6cd810df37..5b9c54b4d4 100644
--- a/src/plugins/qmldesigner/components/bindingeditor/bindingeditorwidget.cpp
+++ b/src/plugins/qmldesigner/components/bindingeditor/bindingeditorwidget.cpp
@@ -35,6 +35,10 @@
#include <qmljseditor/qmljseditordocument.h>
#include <qmljseditor/qmljssemantichighlighter.h>
#include <qmljstools/qmljsindenter.h>
+#include <qmljstools/qmljstoolsconstants.h>
+
+#include <projectexplorer/projectexplorerconstants.h>
+#include <utils/fancylineedit.h>
#include <QAction>
@@ -43,17 +47,19 @@ namespace QmlDesigner {
BindingEditorWidget::BindingEditorWidget()
: m_context(new Core::IContext(this))
{
+ Core::Context context(BINDINGEDITOR_CONTEXT_ID,
+ ProjectExplorer::Constants::QMLJS_LANGUAGE_ID);
+
m_context->setWidget(this);
+ m_context->setContext(context);
Core::ICore::addContextObject(m_context);
- const Core::Context context(BINDINGEDITOR_CONTEXT_ID);
-
/*
* We have to register our own active auto completion shortcut, because the original short cut will
* use the cursor position of the original editor in the editor manager.
*/
-
m_completionAction = new QAction(tr("Trigger Completion"), this);
+
Core::Command *command = Core::ActionManager::registerAction(
m_completionAction, TextEditor::Constants::COMPLETE_THIS, context);
command->setDefaultKeySequence(QKeySequence(
@@ -84,11 +90,9 @@ bool BindingEditorWidget::event(QEvent *event)
{
if (event->type() == QEvent::KeyPress) {
QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event);
- if (keyEvent->key() == Qt::Key_Return || keyEvent->key() == Qt::Key_Enter) {
+ if ((keyEvent->key() == Qt::Key_Return || keyEvent->key() == Qt::Key_Enter) && !keyEvent->modifiers()) {
emit returnKeyClicked();
return true;
- } else {
- return QmlJSEditor::QmlJSEditorWidget::event(event);
}
}
return QmlJSEditor::QmlJSEditorWidget::event(event);
@@ -133,8 +137,12 @@ void BindingDocument::triggerPendingUpdates()
BindingEditorFactory::BindingEditorFactory()
{
setId(BINDINGEDITOR_CONTEXT_ID);
- setDisplayName(QCoreApplication::translate("OpenWith::Editors", QmlDesigner::BINDINGEDITOR_CONTEXT_ID));
+ setDisplayName(QCoreApplication::translate("OpenWith::Editors", BINDINGEDITOR_CONTEXT_ID));
setEditorActionHandlers(0);
+ addMimeType(BINDINGEDITOR_CONTEXT_ID);
+ addMimeType(QmlJSTools::Constants::QML_MIMETYPE);
+ addMimeType(QmlJSTools::Constants::QMLTYPES_MIMETYPE);
+ addMimeType(QmlJSTools::Constants::JS_MIMETYPE);
setDocumentCreator([]() { return new BindingDocument; });
setEditorWidgetCreator([]() { return new BindingEditorWidget; });
diff --git a/src/plugins/qmldesigner/components/componentcore/designeractionmanager.cpp b/src/plugins/qmldesigner/components/componentcore/designeractionmanager.cpp
index 8ca977e742..d9a67a8400 100644
--- a/src/plugins/qmldesigner/components/componentcore/designeractionmanager.cpp
+++ b/src/plugins/qmldesigner/components/componentcore/designeractionmanager.cpp
@@ -290,8 +290,8 @@ QHash<QString, QStringList> DesignerActionManager::handleExternalAssetsDrop(cons
for (const QString &category : categories) {
AddResourceOperation operation = categoryOperation.value(category);
QStringList files = categoryFiles.value(category);
- bool success = operation(files, {});
- if (success)
+ AddFilesResult result = operation(files, {});
+ if (result == AddFilesResult::Succeeded)
addedCategoryFiles.insert(category, files);
}
diff --git a/src/plugins/qmldesigner/components/componentcore/designeractionmanager.h b/src/plugins/qmldesigner/components/componentcore/designeractionmanager.h
index 60e2c7562f..e86e441b14 100644
--- a/src/plugins/qmldesigner/components/componentcore/designeractionmanager.h
+++ b/src/plugins/qmldesigner/components/componentcore/designeractionmanager.h
@@ -28,6 +28,7 @@
#include <qmldesignercorelib_global.h>
#include "actioninterface.h"
#include "modelnode.h"
+#include "modelnodeoperations.h"
#include <coreplugin/actionmanager/command.h>
#include <utils/styledbar.h>
@@ -45,7 +46,7 @@ namespace QmlDesigner {
class DesignerActionManagerView;
-using AddResourceOperation = std::function<bool (const QStringList &, const QString &)>;
+using AddResourceOperation = std::function<AddFilesResult (const QStringList &, const QString &)>;
using ModelNodePreviewImageOperation = std::function<QVariant (const ModelNode &)>;
struct AddResourceHandler
diff --git a/src/plugins/qmldesigner/components/componentcore/modelnodeoperations.cpp b/src/plugins/qmldesigner/components/componentcore/modelnodeoperations.cpp
index ab2853354c..b486740495 100644
--- a/src/plugins/qmldesigner/components/componentcore/modelnodeoperations.cpp
+++ b/src/plugins/qmldesigner/components/componentcore/modelnodeoperations.cpp
@@ -992,13 +992,15 @@ Utils::FilePath projectFilePath()
return Utils::FilePath();
}
-static bool addFilesToProject(const QStringList &fileNames, const QString &defaultDirectory)
+static AddFilesResult addFilesToProject(const QStringList &fileNames, const QString &defaultDirectory)
{
QString directory = AddImagesDialog::getDirectory(fileNames, defaultDirectory);
if (directory.isEmpty())
- return false;
+ return AddFilesResult::Cancelled;
+
+ DesignDocument *document = QmlDesignerPlugin::instance()->currentDesignDocument();
+ QTC_ASSERT(document, return AddFilesResult::Failed);
- bool allSuccessful = true;
QList<QPair<QString, QString>> copyList;
QStringList removeList;
for (const QString &fileName : fileNames) {
@@ -1021,26 +1023,21 @@ static bool addFilesToProject(const QStringList &fileNames, const QString &defau
// unnecessarily refreshing file models multiple times during the operation
for (const auto &file : qAsConst(removeList))
QFile::remove(file);
+
for (const auto &filePair : qAsConst(copyList)) {
const bool success = QFile::copy(filePair.first, filePair.second);
-
- auto document = QmlDesignerPlugin::instance()->currentDesignDocument();
-
- QTC_ASSERT(document, return false);
-
- if (success) {
- ProjectExplorer::Node *node = ProjectExplorer::ProjectTree::nodeForFile(document->fileName());
- if (node) {
- ProjectExplorer::FolderNode *containingFolder = node->parentFolderNode();
- if (containingFolder)
- containingFolder->addFiles({Utils::FilePath::fromString(filePair.second)});
- }
- } else {
- allSuccessful = false;
+ if (!success)
+ return AddFilesResult::Failed;
+
+ ProjectExplorer::Node *node = ProjectExplorer::ProjectTree::nodeForFile(document->fileName());
+ if (node) {
+ ProjectExplorer::FolderNode *containingFolder = node->parentFolderNode();
+ if (containingFolder)
+ containingFolder->addFiles({Utils::FilePath::fromString(filePair.second)});
}
}
- return allSuccessful;
+ return AddFilesResult::Succeeded;
}
static QString getAssetDefaultDirectory(const QString &assetDir, const QString &defaultDirectory)
@@ -1060,22 +1057,22 @@ static QString getAssetDefaultDirectory(const QString &assetDir, const QString &
return adjustedDefaultDirectory;
}
-bool addFontToProject(const QStringList &fileNames, const QString &defaultDirectory)
+AddFilesResult addFontToProject(const QStringList &fileNames, const QString &defaultDirectory)
{
return addFilesToProject(fileNames, getAssetDefaultDirectory("fonts", defaultDirectory));
}
-bool addSoundToProject(const QStringList &fileNames, const QString &defaultDirectory)
+AddFilesResult addSoundToProject(const QStringList &fileNames, const QString &defaultDirectory)
{
return addFilesToProject(fileNames, getAssetDefaultDirectory("sounds", defaultDirectory));
}
-bool addShaderToProject(const QStringList &fileNames, const QString &defaultDirectory)
+AddFilesResult addShaderToProject(const QStringList &fileNames, const QString &defaultDirectory)
{
return addFilesToProject(fileNames, getAssetDefaultDirectory("shaders", defaultDirectory));
}
-bool addImageToProject(const QStringList &fileNames, const QString &defaultDirectory)
+AddFilesResult addImageToProject(const QStringList &fileNames, const QString &defaultDirectory)
{
return addFilesToProject(fileNames, getAssetDefaultDirectory("images", defaultDirectory));
}
diff --git a/src/plugins/qmldesigner/components/componentcore/modelnodeoperations.h b/src/plugins/qmldesigner/components/componentcore/modelnodeoperations.h
index 0e302a3c65..feb7faa556 100644
--- a/src/plugins/qmldesigner/components/componentcore/modelnodeoperations.h
+++ b/src/plugins/qmldesigner/components/componentcore/modelnodeoperations.h
@@ -28,6 +28,9 @@
#include "selectioncontext.h"
namespace QmlDesigner {
+
+enum class AddFilesResult { Succeeded, Failed, Cancelled };
+
namespace ModelNodeOperations {
bool goIntoComponent(const ModelNode &modelNode);
@@ -73,10 +76,10 @@ void addItemToStackedContainer(const SelectionContext &selectionContext);
void increaseIndexOfStackedContainer(const SelectionContext &selectionContext);
void decreaseIndexOfStackedContainer(const SelectionContext &selectionContext);
void addTabBarToStackedContainer(const SelectionContext &selectionContext);
-bool addImageToProject(const QStringList &fileNames, const QString &directory);
-bool addFontToProject(const QStringList &fileNames, const QString &directory);
-bool addSoundToProject(const QStringList &fileNames, const QString &directory);
-bool addShaderToProject(const QStringList &fileNames, const QString &directory);
+AddFilesResult addImageToProject(const QStringList &fileNames, const QString &directory);
+AddFilesResult addFontToProject(const QStringList &fileNames, const QString &directory);
+AddFilesResult addSoundToProject(const QStringList &fileNames, const QString &directory);
+AddFilesResult addShaderToProject(const QStringList &fileNames, const QString &directory);
void createFlowActionArea(const SelectionContext &selectionContext);
void addTransition(const SelectionContext &selectionState);
void addFlowEffect(const SelectionContext &selectionState, const TypeName &typeName);
diff --git a/src/plugins/qmldesigner/components/connectioneditor/connectionviewwidget.cpp b/src/plugins/qmldesigner/components/connectioneditor/connectionviewwidget.cpp
index 11bfebe5e7..095b8b6262 100644
--- a/src/plugins/qmldesigner/components/connectioneditor/connectionviewwidget.cpp
+++ b/src/plugins/qmldesigner/components/connectioneditor/connectionviewwidget.cpp
@@ -159,17 +159,20 @@ void ConnectionViewWidget::contextMenuEvent(QContextMenuEvent *event)
QMenu menu(this);
- menu.addAction(tr("Open Connection Editor"), [&]() {
+ menu.addAction(tr("Open Connection Editor"), this, [&]() {
auto *connectionModel = qobject_cast<ConnectionModel *>(targetView->model());
const SignalHandlerProperty property = connectionModel->signalHandlerPropertyForRow(index.row());
const ModelNode node = property.parentModelNode();
+ const QString targetName = index.siblingAtColumn(ConnectionModel::TargetModelNodeRow).data().toString()
+ + "." + property.name();
+
m_connectionEditor->showWidget();
m_connectionEditor->setConnectionValue(index.data().toString());
m_connectionEditor->setModelIndex(index);
m_connectionEditor->setModelNode(node);
m_connectionEditor->prepareConnections();
- m_connectionEditor->updateWindowName();
+ m_connectionEditor->updateWindowName(targetName);
});
QMap<QString, QVariant> data;
@@ -179,7 +182,7 @@ void ConnectionViewWidget::contextMenuEvent(QContextMenuEvent *event)
const auto actions = designerActionManager.actionsForTargetView(
ActionInterface::TargetView::ConnectionEditor);
- for (auto actionInterface : actions) {
+ for (const auto &actionInterface : actions) {
auto *action = actionInterface->action();
action->setData(data);
menu.addAction(action);
@@ -198,7 +201,7 @@ void ConnectionViewWidget::contextMenuEvent(QContextMenuEvent *event)
QMenu menu(this);
- menu.addAction(tr("Open Binding Editor"), [&]() {
+ menu.addAction(tr("Open Binding Editor"), this, [&]() {
BindingModel *bindingModel = qobject_cast<BindingModel*>(targetView->model());
const BindingProperty property = bindingModel->bindingPropertyForRow(index.row());
@@ -209,10 +212,13 @@ void ConnectionViewWidget::contextMenuEvent(QContextMenuEvent *event)
const TypeName typeName = property.isDynamic() ? property.dynamicTypeName()
: node.metaInfo().propertyTypeName(property.name());
+ const QString targetName = node.displayName() + "." + property.name();
+
m_bindingEditor->showWidget();
m_bindingEditor->setBindingValue(property.expression());
m_bindingEditor->setModelNode(node);
m_bindingEditor->setBackendValueTypeName(typeName);
+ m_bindingEditor->setTargetName(targetName);
m_bindingEditor->prepareBindings();
m_bindingEditor->updateWindowName();
@@ -232,7 +238,7 @@ void ConnectionViewWidget::contextMenuEvent(QContextMenuEvent *event)
DynamicPropertiesModel *propertiesModel = qobject_cast<DynamicPropertiesModel *>(targetView->model());
QMenu menu(this);
- menu.addAction(tr("Open Binding Editor"), [&]() {
+ menu.addAction(tr("Open Binding Editor"), this, [&]() {
AbstractProperty abstractProperty = propertiesModel->abstractPropertyForRow(index.row());
if (!abstractProperty.isValid())
return;
@@ -247,17 +253,20 @@ void ConnectionViewWidget::contextMenuEvent(QContextMenuEvent *event)
else
return;
+ const QString targetName = node.displayName() + "." + abstractProperty.name();
+
m_dynamicEditor->showWidget();
m_dynamicEditor->setBindingValue(newExpression);
m_dynamicEditor->setModelNode(node);
m_dynamicEditor->setBackendValueTypeName(abstractProperty.dynamicTypeName());
+ m_dynamicEditor->setTargetName(targetName);
m_dynamicEditor->prepareBindings();
m_dynamicEditor->updateWindowName();
m_dynamicIndex = index;
});
- menu.addAction(tr("Reset Property"), [&]() {
+ menu.addAction(tr("Reset Property"), this, [&]() {
propertiesModel->resetProperty(propertiesModel->abstractPropertyForRow(index.row()).name());
});
diff --git a/src/plugins/qmldesigner/components/formeditor/formeditorview.cpp b/src/plugins/qmldesigner/components/formeditor/formeditorview.cpp
index 10e1373dde..187bc4ca17 100644
--- a/src/plugins/qmldesigner/components/formeditor/formeditorview.cpp
+++ b/src/plugins/qmldesigner/components/formeditor/formeditorview.cpp
@@ -339,26 +339,13 @@ static inline bool hasNodeSourceParent(const ModelNode &node)
void FormEditorView::nodeReparented(const ModelNode &node, const NodeAbstractProperty &/*newPropertyParent*/, const NodeAbstractProperty &/*oldPropertyParent*/, AbstractView::PropertyChangeFlags /*propertyChange*/)
{
- // If node is not connected to scene root, don't do anything yet to avoid duplicated effort,
- // as any removal or addition will remove or add descendants as well.
- if (!node.isInHierarchy())
- return;
+ addOrRemoveFormEditorItem(node);
+}
- QmlItemNode itemNode(node);
- if (hasNodeSourceParent(node)) {
- if (FormEditorItem *item = m_scene->itemForQmlItemNode(itemNode)) {
- QList<FormEditorItem *> removed = scene()->itemsForQmlItemNodes(itemNode.allSubModelNodes());
- removed.append(item);
- m_currentTool->itemsAboutToRemoved(removed);
- removeNodeFromScene(itemNode);
- }
- } else if (itemNode.isValid() && node.nodeSourceType() == ModelNode::NodeWithoutSource) {
- if (!m_scene->itemForQmlItemNode(itemNode)) {
- setupFormEditorItemTree(itemNode);
- // Simulate selection change to refresh tools
- selectedNodesChanged(selectedModelNodes(), {});
- }
- }
+void FormEditorView::nodeSourceChanged(const ModelNode &node, const QString &newNodeSource)
+{
+ Q_UNUSED(newNodeSource)
+ addOrRemoveFormEditorItem(node);
}
WidgetInfo FormEditorView::widgetInfo()
@@ -863,6 +850,38 @@ void FormEditorView::resetNodeInstanceView()
resetPuppet();
}
+void FormEditorView::addOrRemoveFormEditorItem(const ModelNode &node)
+{
+ // If node is not connected to scene root, don't do anything yet to avoid duplicated effort,
+ // as any removal or addition will remove or add descendants as well.
+ if (!node.isInHierarchy())
+ return;
+
+ QmlItemNode itemNode(node);
+
+ auto removeItemFromScene = [this, &itemNode]() {
+ if (FormEditorItem *item = m_scene->itemForQmlItemNode(itemNode)) {
+ QList<FormEditorItem *> removed = scene()->itemsForQmlItemNodes(itemNode.allSubModelNodes());
+ removed.append(item);
+ m_currentTool->itemsAboutToRemoved(removed);
+ removeNodeFromScene(itemNode);
+ }
+ };
+ if (hasNodeSourceParent(node)) {
+ removeItemFromScene();
+ } else if (itemNode.isValid()) {
+ if (node.nodeSourceType() == ModelNode::NodeWithoutSource) {
+ if (!m_scene->itemForQmlItemNode(itemNode)) {
+ setupFormEditorItemTree(itemNode);
+ // Simulate selection change to refresh tools
+ selectedNodesChanged(selectedModelNodes(), {});
+ }
+ } else {
+ removeItemFromScene();
+ }
+ }
+}
+
void FormEditorView::reset()
{
QTimer::singleShot(200, this, &FormEditorView::delayedReset);
diff --git a/src/plugins/qmldesigner/components/formeditor/formeditorview.h b/src/plugins/qmldesigner/components/formeditor/formeditorview.h
index 04b7d1e83e..ca3fb72bb0 100644
--- a/src/plugins/qmldesigner/components/formeditor/formeditorview.h
+++ b/src/plugins/qmldesigner/components/formeditor/formeditorview.h
@@ -70,6 +70,7 @@ public:
void nodeCreated(const ModelNode &createdNode) override;
void nodeAboutToBeRemoved(const ModelNode &removedNode) override;
void nodeReparented(const ModelNode &node, const NodeAbstractProperty &newPropertyParent, const NodeAbstractProperty &oldPropertyParent, AbstractView::PropertyChangeFlags propertyChange) override;
+ void nodeSourceChanged(const ModelNode &node, const QString &newNodeSource) override;
void nodeIdChanged(const ModelNode& node, const QString& newId, const QString& oldId) override;
void propertiesAboutToBeRemoved(const QList<AbstractProperty>& propertyList) override;
void rootNodeTypeChanged(const QString &type, int majorVersion, int minorVersion) override;
@@ -147,6 +148,7 @@ private:
void createFormEditorWidget();
void temporaryBlockView(int duration = 1000);
void resetNodeInstanceView();
+ void addOrRemoveFormEditorItem(const ModelNode &node);
QPointer<FormEditorWidget> m_formEditorWidget;
QPointer<FormEditorScene> m_scene;
diff --git a/src/plugins/qmldesigner/components/integration/designdocument.cpp b/src/plugins/qmldesigner/components/integration/designdocument.cpp
index 9374e61776..0b7d7fa2c9 100644
--- a/src/plugins/qmldesigner/components/integration/designdocument.cpp
+++ b/src/plugins/qmldesigner/components/integration/designdocument.cpp
@@ -634,8 +634,11 @@ void DesignDocument::setEditor(Core::IEditor *editor)
connect(Core::EditorManager::instance(), &Core::EditorManager::aboutToSave,
this, [this](Core::IDocument *document) {
if (m_textEditor && m_textEditor->document() == document) {
- if (m_documentModel && m_documentModel->rewriterView())
+ if (m_documentModel && m_documentModel->rewriterView()) {
+ if (fileName().completeSuffix() == "ui.qml")
+ m_documentModel->rewriterView()->sanitizeModel();
m_documentModel->rewriterView()->writeAuxiliaryData();
+ }
}
});
diff --git a/src/plugins/qmldesigner/components/itemlibrary/itemlibraryassetimportdialog.cpp b/src/plugins/qmldesigner/components/itemlibrary/itemlibraryassetimportdialog.cpp
index 04bc51284b..135eaaf5aa 100644
--- a/src/plugins/qmldesigner/components/itemlibrary/itemlibraryassetimportdialog.cpp
+++ b/src/plugins/qmldesigner/components/itemlibrary/itemlibraryassetimportdialog.cpp
@@ -788,7 +788,10 @@ void ItemLibraryAssetImportDialog::onClose()
addInfo(tr("Canceling import."));
m_importer.cancelImport();
} else {
- reject();
+ if (ui->progressBar->value() == 100) // import done successfully
+ accept();
+ else
+ reject();
close();
deleteLater();
}
diff --git a/src/plugins/qmldesigner/components/itemlibrary/itemlibrarycategoriesmodel.cpp b/src/plugins/qmldesigner/components/itemlibrary/itemlibrarycategoriesmodel.cpp
index d351232e36..4962f5d6b4 100644
--- a/src/plugins/qmldesigner/components/itemlibrary/itemlibrarycategoriesmodel.cpp
+++ b/src/plugins/qmldesigner/components/itemlibrary/itemlibrarycategoriesmodel.cpp
@@ -147,20 +147,19 @@ void ItemLibraryCategoriesModel::resetModel()
bool ItemLibraryCategoriesModel::isAllCategoriesHidden() const
{
for (const auto &category : std::as_const(m_categoryList)) {
- // ignore "All Other Components" as its categoryVisible is always true
- if (category->isCategoryVisible() && category->categoryName() != "All Other Components")
+ if (category->isCategoryVisible())
return false;
}
return true;
}
-void ItemLibraryCategoriesModel::showAllCategories(bool show)
+void ItemLibraryCategoriesModel::showAllCategories()
{
for (const auto &category : std::as_const(m_categoryList)) {
- if (category->isCategoryVisible() != show) {
- category->setCategoryVisible(show);
- ItemLibraryModel::saveCategoryVisibleState(show, category->categoryName(),
+ if (!category->isCategoryVisible()) {
+ category->setCategoryVisible(true);
+ ItemLibraryModel::saveCategoryVisibleState(true, category->categoryName(),
category->ownerImport()->importName());
}
}
@@ -168,37 +167,56 @@ void ItemLibraryCategoriesModel::showAllCategories(bool show)
emit dataChanged(index(0), index(m_categoryList.size() - 1), {m_roleNames.key("categoryVisible")});
}
-QObject *ItemLibraryCategoriesModel::selectFirstVisibleCategory()
+void ItemLibraryCategoriesModel::hideCategory(const QString &categoryName)
+{
+ for (int i = 0; i < m_categoryList.size(); ++i) {
+ const auto category = m_categoryList.at(i);
+ if (category->categoryName() == categoryName) {
+ category->setCategoryVisible(false);
+ ItemLibraryModel::saveCategoryVisibleState(false, category->categoryName(),
+ category->ownerImport()->importName());
+ emit dataChanged(index(i), index(i), {m_roleNames.key("categoryVisible")});
+ break;
+ }
+ }
+}
+
+int ItemLibraryCategoriesModel::selectFirstVisibleCategory()
{
for (int i = 0; i < m_categoryList.length(); ++i) {
const auto category = m_categoryList.at(i);
if (category->isCategoryVisible()) {
category->setCategorySelected(true);
- emit dataChanged(index(i),index(i), {m_roleNames.key("categorySelected")});
- return category;
+ emit dataChanged(index(i), index(i), {m_roleNames.key("categorySelected")});
+ return i;
}
}
- return nullptr;
+ return -1;
}
-void ItemLibraryCategoriesModel::clearSelectedCategories()
+void ItemLibraryCategoriesModel::clearSelectedCategory(int categoryIndex)
{
- for (const auto &category : std::as_const(m_categoryList))
- category->setCategorySelected(false);
+ if (categoryIndex == -1 || m_categoryList.isEmpty())
+ return;
- emit dataChanged(index(0), index(m_categoryList.size() - 1), {m_roleNames.key("categorySelected")});
+ m_categoryList.at(categoryIndex)->setCategorySelected(false);
+ emit dataChanged(index(categoryIndex), index(categoryIndex), {m_roleNames.key("categorySelected")});
}
-void ItemLibraryCategoriesModel::selectCategory(int categoryIndex)
+QPointer<ItemLibraryCategory> ItemLibraryCategoriesModel::selectCategory(int categoryIndex)
{
- const auto category = m_categoryList.at(categoryIndex);
+ if (categoryIndex == -1 || m_categoryList.isEmpty())
+ return nullptr;
+
+ const QPointer<ItemLibraryCategory> category = m_categoryList.at(categoryIndex);
if (!category->categorySelected()) {
- clearSelectedCategories();
category->setCategorySelected(true);
emit dataChanged(index(categoryIndex),index(categoryIndex), {m_roleNames.key("categorySelected")});
}
+
+ return category;
}
void ItemLibraryCategoriesModel::addRoleNames()
diff --git a/src/plugins/qmldesigner/components/itemlibrary/itemlibrarycategoriesmodel.h b/src/plugins/qmldesigner/components/itemlibrary/itemlibrarycategoriesmodel.h
index 9433af804f..36437a0ed6 100644
--- a/src/plugins/qmldesigner/components/itemlibrary/itemlibrarycategoriesmodel.h
+++ b/src/plugins/qmldesigner/components/itemlibrary/itemlibrarycategoriesmodel.h
@@ -55,10 +55,11 @@ public:
bool isAllCategoriesHidden() const;
void sortCategorySections();
void resetModel();
- void showAllCategories(bool show = true);
- void clearSelectedCategories();
- QObject *selectFirstVisibleCategory();
- void selectCategory(int categoryIndex);
+ void showAllCategories();
+ void hideCategory(const QString &categoryName);
+ void clearSelectedCategory(int categoryIndex);
+ int selectFirstVisibleCategory();
+ QPointer<ItemLibraryCategory> selectCategory(int categoryIndex);
private:
void addRoleNames();
diff --git a/src/plugins/qmldesigner/components/itemlibrary/itemlibrarycategory.cpp b/src/plugins/qmldesigner/components/itemlibrary/itemlibrarycategory.cpp
index 0744b7b2b3..ce04b298fe 100644
--- a/src/plugins/qmldesigner/components/itemlibrary/itemlibrarycategory.cpp
+++ b/src/plugins/qmldesigner/components/itemlibrary/itemlibrarycategory.cpp
@@ -137,6 +137,7 @@ void ItemLibraryCategory::setExpanded(bool expanded)
void ItemLibraryCategory::setCategorySelected(bool selected)
{
m_categorySelected = selected;
+ emit categorySelectedChanged();
}
} // namespace QmlDesigner
diff --git a/src/plugins/qmldesigner/components/itemlibrary/itemlibraryimport.cpp b/src/plugins/qmldesigner/components/itemlibrary/itemlibraryimport.cpp
index 7e696e43ef..ebf13d0fe5 100644
--- a/src/plugins/qmldesigner/components/itemlibrary/itemlibraryimport.cpp
+++ b/src/plugins/qmldesigner/components/itemlibrary/itemlibraryimport.cpp
@@ -133,28 +133,38 @@ bool ItemLibraryImport::updateCategoryVisibility(const QString &searchText, bool
return hasVisibleCategories;
}
-void ItemLibraryImport::showAllCategories(bool show)
+void ItemLibraryImport::showAllCategories()
{
- m_categoryModel.showAllCategories(show);
+ m_categoryModel.showAllCategories();
+ setAllCategoriesVisible(true);
}
-void ItemLibraryImport::selectCategory(int categoryIndex)
+void ItemLibraryImport::hideCategory(const QString &categoryName)
{
- m_categoryModel.selectCategory(categoryIndex);
+ m_categoryModel.hideCategory(categoryName);
+ setAllCategoriesVisible(false);
}
-QObject *ItemLibraryImport::selectFirstVisibleCategory()
+ItemLibraryCategory *ItemLibraryImport::selectCategory(int categoryIndex)
+{
+ return m_categoryModel.selectCategory(categoryIndex);
+}
+
+int ItemLibraryImport::selectFirstVisibleCategory()
{
return m_categoryModel.selectFirstVisibleCategory();
}
-void ItemLibraryImport::clearSelectedCategories()
+void ItemLibraryImport::clearSelectedCategory(int categoryIndex)
{
- m_categoryModel.clearSelectedCategories();
+ m_categoryModel.clearSelectedCategory(categoryIndex);
}
bool ItemLibraryImport::isAllCategoriesHidden() const
{
+ if (!m_isVisible)
+ return true;
+
return m_categoryModel.isAllCategoriesHidden();
}
@@ -221,7 +231,7 @@ void ItemLibraryImport::setImportExpanded(bool expanded)
}
}
-ItemLibraryCategory *ItemLibraryImport::getCategorySection(const QString &categoryName) const
+ItemLibraryCategory *ItemLibraryImport::getCategoryByName(const QString &categoryName) const
{
for (ItemLibraryCategory *catSec : std::as_const(m_categoryModel.categorySections())) {
if (catSec->categoryName() == categoryName)
@@ -231,6 +241,16 @@ ItemLibraryCategory *ItemLibraryImport::getCategorySection(const QString &catego
return nullptr;
}
+ItemLibraryCategory *ItemLibraryImport::getCategoryAt(int categoryIndex) const
+{
+ const QList<QPointer<ItemLibraryCategory>> categories = m_categoryModel.categorySections();
+
+ if (categoryIndex != -1 && !categories.isEmpty())
+ return categories.at(categoryIndex);
+
+ return nullptr;
+}
+
// static
QString ItemLibraryImport::userComponentsTitle()
{
@@ -264,22 +284,14 @@ void ItemLibraryImport::updateRemovable()
}
}
-// returns true if all categories are visible, otherwise false
-bool ItemLibraryImport::importCatVisibleState() const
+bool ItemLibraryImport::allCategoriesVisible() const
{
- if (m_categoryModel.rowCount() > 0) {
- for (ItemLibraryCategory *cat : m_categoryModel.categorySections()) {
- if (!cat->isCategoryVisible())
- return false;
- }
- }
-
- return true;
+ return m_allCategoriesVisible;
}
-void ItemLibraryImport::setImportCatVisibleState(bool show)
+void ItemLibraryImport::setAllCategoriesVisible(bool visible)
{
- m_categoryModel.showAllCategories(show);
+ m_allCategoriesVisible = visible;
}
} // namespace QmlDesigner
diff --git a/src/plugins/qmldesigner/components/itemlibrary/itemlibraryimport.h b/src/plugins/qmldesigner/components/itemlibrary/itemlibraryimport.h
index f5a1cd0279..89aaca8e02 100644
--- a/src/plugins/qmldesigner/components/itemlibrary/itemlibraryimport.h
+++ b/src/plugins/qmldesigner/components/itemlibrary/itemlibraryimport.h
@@ -43,7 +43,7 @@ class ItemLibraryImport : public QObject
Q_PROPERTY(bool importExpanded READ importExpanded WRITE setImportExpanded NOTIFY importExpandChanged FINAL)
Q_PROPERTY(bool importRemovable READ importRemovable NOTIFY importRemovableChanged FINAL)
Q_PROPERTY(bool importUnimported READ importUnimported FINAL)
- Q_PROPERTY(bool importCatVisibleState READ importCatVisibleState WRITE setImportCatVisibleState NOTIFY importCatVisibleStateChanged FINAL)
+ Q_PROPERTY(bool allCategoriesVisible READ allCategoriesVisible WRITE setAllCategoriesVisible NOTIFY allCategoriesVisibleChanged FINAL)
Q_PROPERTY(QObject *categoryModel READ categoryModel NOTIFY categoryModelChanged FINAL)
public:
@@ -65,11 +65,12 @@ public:
bool importVisible() const;
bool importUsed() const;
bool importRemovable() const;
- bool importCatVisibleState() const;
+ bool allCategoriesVisible() const;
bool hasCategories() const;
bool hasSingleCategory() const;
bool isAllCategoriesHidden() const;
- ItemLibraryCategory *getCategorySection(const QString &categoryName) const;
+ ItemLibraryCategory *getCategoryByName(const QString &categoryName) const;
+ ItemLibraryCategory *getCategoryAt(int categoryIndex) const;
void addCategory(ItemLibraryCategory *category);
QObject *categoryModel();
@@ -78,12 +79,14 @@ public:
void setImportUsed(bool importUsed);
void sortCategorySections();
void setImportExpanded(bool expanded = true);
- void setImportCatVisibleState(bool show);
+ void setAllCategoriesVisible(bool visible);
void expandCategories(bool expand = true);
- void showAllCategories(bool show = true);
- void selectCategory(int categoryIndex);
- QObject *selectFirstVisibleCategory();
- void clearSelectedCategories();
+ void showAllCategories();
+ void hideCategory(const QString &categoryName);
+ ItemLibraryCategory *selectCategory(int categoryIndex);
+ int selectFirstVisibleCategory();
+ void clearSelectedCategory(int categoryIndex);
+ bool importUnimported() const { return m_sectionType == SectionType::Unimported; }
static QString userComponentsTitle();
static QString quick3DAssetsTitle();
@@ -97,17 +100,17 @@ signals:
void importUsedChanged();
void importExpandChanged();
void importRemovableChanged();
- void importCatVisibleStateChanged();
+ void allCategoriesVisibleChanged();
private:
void updateRemovable();
- bool importUnimported() const { return m_sectionType == SectionType::Unimported; }
Import m_import;
bool m_importExpanded = true;
bool m_isVisible = true;
bool m_importUsed = false;
bool m_importRemovable = false;
+ bool m_allCategoriesVisible = true;
SectionType m_sectionType = SectionType::Default;
ItemLibraryCategoriesModel m_categoryModel;
};
diff --git a/src/plugins/qmldesigner/components/itemlibrary/itemlibrarymodel.cpp b/src/plugins/qmldesigner/components/itemlibrary/itemlibrarymodel.cpp
index ebef71f63f..b571cc4981 100644
--- a/src/plugins/qmldesigner/components/itemlibrary/itemlibrarymodel.cpp
+++ b/src/plugins/qmldesigner/components/itemlibrary/itemlibrarymodel.cpp
@@ -59,8 +59,8 @@ bool ItemLibraryModel::loadExpandedState(const QString &sectionName)
return expandedStateHash.value(sectionName, true);
}
-void ItemLibraryModel::saveCategoryVisibleState(bool isVisible, const QString &categoryName, const
- QString &importName)
+void ItemLibraryModel::saveCategoryVisibleState(bool isVisible, const QString &categoryName,
+ const QString &importName)
{
categoryVisibleStateHash.insert(categoryName + '_' + importName, isVisible);
}
@@ -70,58 +70,61 @@ bool ItemLibraryModel::loadCategoryVisibleState(const QString &categoryName, con
return categoryVisibleStateHash.value(categoryName + '_' + importName, true);
}
-void ItemLibraryModel::showHiddenCategories()
+void ItemLibraryModel::selectImportCategory(const QString &importUrl, int categoryIndex)
{
- for (const QPointer<ItemLibraryImport> &import : std::as_const(m_importList)) {
- if (import->hasCategories())
- import->showAllCategories(true);
- }
-
- categoryVisibleStateHash.clear();
-}
+ clearSelectedCategory();
-bool ItemLibraryModel::getIsAnyCategoryHidden() const
-{
- for (const bool &catState : std::as_const(categoryVisibleStateHash)) {
- if (!catState)
- return true;
- }
+ m_selectedImportUrl = importUrl;
+ m_selectedCategoryIndex = categoryIndex;
- return false;
+ updateSelection();
}
-void ItemLibraryModel::selectImportCategory(const QString importUrl, int categoryIndex)
+void ItemLibraryModel::clearSelectedCategory()
{
- ItemLibraryImport *selectedCategoryImport = importByUrl(importUrl);
-
- for (int i = 0; i < m_importList.length(); ++i) {
- const auto importToSelect = m_importList.at(i);
-
- if (selectedCategoryImport == importToSelect)
- importToSelect->selectCategory(categoryIndex);
- else
- importToSelect->clearSelectedCategories();
+ if (m_selectedCategoryIndex != -1) {
+ ItemLibraryImport *selectedImport = importByUrl(m_selectedImportUrl);
+ if (selectedImport)
+ selectedImport->clearSelectedCategory(m_selectedCategoryIndex);
}
}
-bool ItemLibraryModel::isAllCategoriesHidden() const
+void ItemLibraryModel::selectImportFirstVisibleCategory()
{
- for (int i = 0; i < m_importList.length(); ++i) {
- if (!m_importList.at(i)->isAllCategoriesHidden())
- return false;
- }
+ if (m_selectedCategoryIndex != -1) {
+ ItemLibraryImport *selectedImport = importByUrl(m_selectedImportUrl);
+ if (selectedImport) {
+ ItemLibraryCategory *selectedCategory = selectedImport->getCategoryAt(m_selectedCategoryIndex);
+ if (selectedCategory) {
+ bool isUnimported = selectedImport->sectionType() == ItemLibraryImport::SectionType::Unimported;
+ // unimported category is always visible so checking its Import visibility instead
+ bool isVisible = isUnimported ? selectedImport->importVisible()
+ : selectedCategory->isCategoryVisible();
+ if (isVisible)
+ return; // there is already a selected visible category
- return true;
-}
+ clearSelectedCategory();
+ }
+ }
+ }
-QObject *ItemLibraryModel::selectImportFirstVisibleCategory()
-{
for (const QPointer<ItemLibraryImport> &import : std::as_const(m_importList)) {
- if (!import->isAllCategoriesHidden())
- return import->selectFirstVisibleCategory();
+ if (!import->isAllCategoriesHidden()) {
+ m_selectedImportUrl = import->importUrl();
+ m_selectedCategoryIndex = import->selectFirstVisibleCategory();
+
+ ItemLibraryCategory *selectedCategory = import->getCategoryAt(m_selectedCategoryIndex);
+ if (selectedCategory) {
+ setItemsModel(selectedCategory->itemModel());
+ setImportUnimportedSelected(import->importUnimported());
+ return;
+ }
+ }
}
- return nullptr;
+ m_selectedImportUrl.clear();
+ m_selectedCategoryIndex = -1;
+ setItemsModel(nullptr);
}
bool ItemLibraryModel::isAnyCategoryHidden() const
@@ -137,6 +140,30 @@ void ItemLibraryModel::setIsAnyCategoryHidden(bool state)
}
}
+bool ItemLibraryModel::importUnimportedSelected() const
+{
+ return m_importUnimportedSelected;
+}
+
+void ItemLibraryModel::setImportUnimportedSelected(bool state)
+{
+ if (state != m_importUnimportedSelected) {
+ m_importUnimportedSelected = state;
+ emit importUnimportedSelectedChanged();
+ }
+}
+
+QObject *ItemLibraryModel::itemsModel() const
+{
+ return m_itemsModel;
+}
+
+void ItemLibraryModel::setItemsModel(QObject *model)
+{
+ m_itemsModel = model;
+ emit itemsModelChanged();
+}
+
void ItemLibraryModel::expandAll()
{
int i = 0;
@@ -164,6 +191,46 @@ void ItemLibraryModel::collapseAll()
}
}
+void ItemLibraryModel::hideCategory(const QString &importUrl, const QString &categoryName)
+{
+ ItemLibraryImport *import = importByUrl(importUrl);
+ if (!import)
+ return;
+
+ import->hideCategory(categoryName);
+
+ selectImportFirstVisibleCategory();
+ setIsAnyCategoryHidden(true);
+}
+
+void ItemLibraryModel::showImportHiddenCategories(const QString &importUrl)
+{
+ ItemLibraryImport *targetImport = nullptr;
+ bool hiddenCatsExist = false;
+ for (const QPointer<ItemLibraryImport> &import : std::as_const(m_importList)) {
+ if (import->importUrl() == importUrl)
+ targetImport = import;
+ else
+ hiddenCatsExist |= !import->allCategoriesVisible();
+ }
+
+ if (targetImport) {
+ targetImport->showAllCategories();
+ updateSelection(); // useful when all categories are hidden
+ setIsAnyCategoryHidden(hiddenCatsExist);
+ }
+}
+
+void ItemLibraryModel::showAllHiddenCategories()
+{
+ for (const QPointer<ItemLibraryImport> &import : std::as_const(m_importList))
+ import->showAllCategories();
+
+ updateSelection(); // useful when all categories are hidden
+ setIsAnyCategoryHidden(false);
+ categoryVisibleStateHash.clear();
+}
+
void ItemLibraryModel::setFlowMode(bool b)
{
m_flowMode = b;
@@ -242,6 +309,8 @@ void ItemLibraryModel::setSearchText(const QString &searchText)
bool changed = false;
updateVisibility(&changed);
+
+ selectImportFirstVisibleCategory();
}
}
@@ -411,7 +480,7 @@ void ItemLibraryModel::update(ItemLibraryInfo *itemLibraryInfo, Model *model)
}
// get or create category section
- ItemLibraryCategory *categorySection = importSection->getCategorySection(catName);
+ ItemLibraryCategory *categorySection = importSection->getCategoryByName(catName);
if (!categorySection) {
categorySection = new ItemLibraryCategory(catName, importSection);
importSection->addCategory(categorySection);
@@ -428,8 +497,11 @@ void ItemLibraryModel::update(ItemLibraryInfo *itemLibraryInfo, Model *model)
}
sortSections();
+
bool changed = false;
updateVisibility(&changed);
+
+ updateSelection();
endResetModel();
}
@@ -453,6 +525,23 @@ void ItemLibraryModel::clearSections()
m_importList.clear();
}
+void ItemLibraryModel::updateSelection()
+{
+ if (m_selectedCategoryIndex != -1) {
+ ItemLibraryImport *selectedImport = importByUrl(m_selectedImportUrl);
+ if (selectedImport) {
+ ItemLibraryCategory *selectedCategory = selectedImport->selectCategory(m_selectedCategoryIndex);
+ if (selectedCategory) {
+ setItemsModel(selectedCategory->itemModel());
+ setImportUnimportedSelected(selectedImport->importUnimported());
+ return;
+ }
+ }
+ }
+
+ selectImportFirstVisibleCategory();
+}
+
void ItemLibraryModel::registerQmlTypes()
{
qmlRegisterAnonymousType<QmlDesigner::ItemLibraryModel>("ItemLibraryModel", 1);
diff --git a/src/plugins/qmldesigner/components/itemlibrary/itemlibrarymodel.h b/src/plugins/qmldesigner/components/itemlibrary/itemlibrarymodel.h
index ad9803821f..7852999edd 100644
--- a/src/plugins/qmldesigner/components/itemlibrary/itemlibrarymodel.h
+++ b/src/plugins/qmldesigner/components/itemlibrary/itemlibrarymodel.h
@@ -33,15 +33,19 @@ QT_FORWARD_DECLARE_CLASS(QMimeData)
namespace QmlDesigner {
-class ItemLibraryInfo;
+class ItemLibraryCategory;
class ItemLibraryEntry;
-class Model;
class ItemLibraryImport;
+class ItemLibraryInfo;
+class Model;
class ItemLibraryModel : public QAbstractListModel
{
Q_OBJECT
+
Q_PROPERTY(bool isAnyCategoryHidden READ isAnyCategoryHidden WRITE setIsAnyCategoryHidden NOTIFY isAnyCategoryHiddenChanged FINAL)
+ Q_PROPERTY(QObject *itemsModel READ itemsModel WRITE setItemsModel NOTIFY itemsModelChanged)
+ Q_PROPERTY(bool importUnimportedSelected READ importUnimportedSelected WRITE setImportUnimportedSelected NOTIFY importUnimportedSelectedChanged)
public:
explicit ItemLibraryModel(QObject *parent = nullptr);
@@ -66,20 +70,26 @@ public:
bool isAnyCategoryHidden() const;
void setIsAnyCategoryHidden(bool state);
+ bool importUnimportedSelected() const;
+ void setImportUnimportedSelected(bool state);
+
+ QObject *itemsModel() const;
+ void setItemsModel(QObject *model);
+
static void registerQmlTypes();
static void saveExpandedState(bool expanded, const QString &sectionName);
static bool loadExpandedState(const QString &sectionName);
static void saveCategoryVisibleState(bool isVisible, const QString &categoryName, const QString
&importName);
static bool loadCategoryVisibleState(const QString &categoryName, const QString &importName);
+ void selectImportFirstVisibleCategory();
Q_INVOKABLE void expandAll();
Q_INVOKABLE void collapseAll();
- Q_INVOKABLE void showHiddenCategories();
- Q_INVOKABLE bool getIsAnyCategoryHidden() const;
- Q_INVOKABLE void selectImportCategory(const QString importUrl, int categoryIndex);
- Q_INVOKABLE QObject *selectImportFirstVisibleCategory();
- Q_INVOKABLE bool isAllCategoriesHidden() const;
+ Q_INVOKABLE void hideCategory(const QString &importUrl, const QString &categoryName);
+ Q_INVOKABLE void showImportHiddenCategories(const QString &importUrl);
+ Q_INVOKABLE void showAllHiddenCategories();
+ Q_INVOKABLE void selectImportCategory(const QString &importUrl, int categoryIndex);
Import entryToImport(const ItemLibraryEntry &entry);
@@ -87,12 +97,18 @@ public:
signals:
void isAnyCategoryHiddenChanged();
+ void importUnimportedSelectedChanged();
+ void selectedCategoryChanged();
+ void selectedImportUrlChanged();
+ void itemsModelChanged();
private:
void updateVisibility(bool *changed);
void addRoleNames();
void sortSections();
void clearSections();
+ void updateSelection();
+ void clearSelectedCategory();
QList<QPointer<ItemLibraryImport>> m_importList;
QHash<int, QByteArray> m_roleNames;
@@ -100,6 +116,10 @@ private:
QString m_searchText;
bool m_flowMode = false;
bool m_isAnyCategoryHidden = false;
+ bool m_importUnimportedSelected = false;
+ QString m_selectedImportUrl;
+ int m_selectedCategoryIndex = -1;
+ QObject *m_itemsModel = nullptr; // items model for the horizontal layout
inline static QHash<QString, bool> expandedStateHash;
inline static QHash<QString, bool> categoryVisibleStateHash;
diff --git a/src/plugins/qmldesigner/components/itemlibrary/itemlibraryview.cpp b/src/plugins/qmldesigner/components/itemlibrary/itemlibraryview.cpp
index 06b84d83f8..9c8b4e09f9 100644
--- a/src/plugins/qmldesigner/components/itemlibrary/itemlibraryview.cpp
+++ b/src/plugins/qmldesigner/components/itemlibrary/itemlibraryview.cpp
@@ -245,13 +245,15 @@ void ItemLibraryView::updateImport3DSupport(const QVariantMap &supportMap)
m_importableExtensions3DMap = extMap;
- auto import3DModelOperation = [this](const QStringList &fileNames, const QString &defaultDir) -> bool {
+ AddResourceOperation import3DModelOperation = [this](const QStringList &fileNames,
+ const QString &defaultDir) -> AddFilesResult {
auto importDlg = new ItemLibraryAssetImportDialog(fileNames, defaultDir,
m_importableExtensions3DMap,
m_importOptions3DMap, {}, {},
Core::ICore::mainWindow());
- importDlg->exec();
- return true;
+ int result = importDlg->exec();
+
+ return result == QDialog::Accepted ? AddFilesResult::Succeeded : AddFilesResult::Cancelled;
};
auto add3DHandler = [&](const QString &group, const QString &ext) {
diff --git a/src/plugins/qmldesigner/components/itemlibrary/itemlibrarywidget.cpp b/src/plugins/qmldesigner/components/itemlibrary/itemlibrarywidget.cpp
index de15fde7cf..ef1e85287a 100644
--- a/src/plugins/qmldesigner/components/itemlibrary/itemlibrarywidget.cpp
+++ b/src/plugins/qmldesigner/components/itemlibrary/itemlibrarywidget.cpp
@@ -38,6 +38,7 @@
#include <itemlibrarymodel.h>
#include <itemlibraryaddimportmodel.h>
#include "itemlibraryassetsiconprovider.h"
+#include "modelnodeoperations.h"
#include <metainfo.h>
#include <model.h>
#include <rewritingexception.h>
@@ -560,45 +561,31 @@ void ItemLibraryWidget::addImportForItem(const QString &importUrl)
void ItemLibraryWidget::addResources(const QStringList &files)
{
- auto document = QmlDesignerPlugin::instance()->currentDesignDocument();
+ DesignDocument *document = QmlDesignerPlugin::instance()->currentDesignDocument();
QTC_ASSERT(document, return);
- QList<AddResourceHandler> handlers = QmlDesignerPlugin::instance()->viewManager().designerActionManager().addResourceHandler();
-
- QMultiMap<QString, QString> map;
- for (const AddResourceHandler &handler : handlers) {
- map.insert(handler.category, handler.filter);
- }
-
- QMap<QString, QString> reverseMap;
- for (const AddResourceHandler &handler : handlers) {
- reverseMap.insert(handler.filter, handler.category);
- }
-
- QMap<QString, int> priorities;
- for (const AddResourceHandler &handler : handlers) {
- priorities.insert(handler.category, handler.piority);
- }
-
- QStringList sortedKeys = map.uniqueKeys();
- Utils::sort(sortedKeys, [&priorities](const QString &first,
- const QString &second){
- return priorities.value(first) < priorities.value(second);
- });
+ const QList<AddResourceHandler> handlers = QmlDesignerPlugin::instance()->viewManager()
+ .designerActionManager().addResourceHandler();
QStringList fileNames = files;
- if (fileNames.isEmpty()) {
- QStringList filters;
-
- for (const QString &key : qAsConst(sortedKeys)) {
- QString str = key + " (";
- str.append(map.values(key).join(" "));
- str.append(")");
- filters.append(str);
+ if (fileNames.isEmpty()) { // if no files, show the "add assets" dialog
+ QMultiMap<QString, QString> map;
+ QHash<QString, int> priorities;
+ for (const AddResourceHandler &handler : handlers) {
+ map.insert(handler.category, handler.filter);
+ priorities.insert(handler.category, handler.piority);
}
- filters.prepend(tr("All Files (%1)").arg(map.values().join(" ")));
+ QStringList sortedKeys = map.uniqueKeys();
+ Utils::sort(sortedKeys, [&priorities](const QString &first, const QString &second) {
+ return priorities.value(first) < priorities.value(second);
+ });
+
+ QStringList filters { tr("All Files (%1)").arg(map.values().join(' ')) };
+ QString filterTemplate = "%1 (%2)";
+ for (const QString &key : qAsConst(sortedKeys))
+ filters.append(filterTemplate.arg(key, map.values(key).join(' ')));
static QString lastDir;
const QString currentDir = lastDir.isEmpty() ? document->fileName().parentDir().toString() : lastDir;
@@ -616,24 +603,30 @@ void ItemLibraryWidget::addResources(const QStringList &files)
}
}
- QMultiMap<QString, QString> partitionedFileNames;
+ QHash<QString, QString> filterToCategory;
+ QHash<QString, AddResourceOperation> categoryToOperation;
+ for (const AddResourceHandler &handler : handlers) {
+ filterToCategory.insert(handler.filter, handler.category);
+ categoryToOperation.insert(handler.category, handler.operation);
+ }
+
+ QMultiMap<QString, QString> categoryFileNames; // filenames grouped by category
for (const QString &fileName : qAsConst(fileNames)) {
const QString suffix = "*." + QFileInfo(fileName).suffix().toLower();
- const QString category = reverseMap.value(suffix);
- partitionedFileNames.insert(category, fileName);
+ const QString category = filterToCategory.value(suffix);
+ categoryFileNames.insert(category, fileName);
}
- for (const QString &category : partitionedFileNames.uniqueKeys()) {
- for (const AddResourceHandler &handler : handlers) {
- QStringList fileNames = partitionedFileNames.values(category);
- if (handler.category == category) {
- QmlDesignerPlugin::emitUsageStatistics(Constants::EVENT_RESOURCE_IMPORTED + category);
- if (!handler.operation(fileNames, document->fileName().parentDir().toString()))
- Core::AsynchronousMessageBox::warning(tr("Failed to Add Files"), tr("Could not add %1 to project.").arg(fileNames.join(" ")));
- break;
- }
- }
+ for (const QString &category : categoryFileNames.uniqueKeys()) {
+ QStringList fileNames = categoryFileNames.values(category);
+ AddResourceOperation operation = categoryToOperation.value(category);
+ QmlDesignerPlugin::emitUsageStatistics(Constants::EVENT_RESOURCE_IMPORTED + category);
+ AddFilesResult result = operation(fileNames, document->fileName().parentDir().toString());
+ if (result == AddFilesResult::Failed) {
+ Core::AsynchronousMessageBox::warning(tr("Failed to Add Files"),
+ tr("Could not add %1 to project.").arg(fileNames.join(' ')));
+ }
}
}
diff --git a/src/plugins/qmldesigner/designercore/include/import.h b/src/plugins/qmldesigner/designercore/include/import.h
index 99612fa2ad..c797a19ae4 100644
--- a/src/plugins/qmldesigner/designercore/include/import.h
+++ b/src/plugins/qmldesigner/designercore/include/import.h
@@ -25,6 +25,8 @@
#pragma once
+#include <utils/porting.h>
+
#include <QString>
#include <QStringList>
#include <QMetaType>
@@ -74,7 +76,7 @@ private:
QStringList m_importPathList;
};
-QMLDESIGNERCORE_EXPORT uint qHash(const Import &import);
+QMLDESIGNERCORE_EXPORT Utils::QHashValueType qHash(const Import &import);
} // namespace QmlDesigner
diff --git a/src/plugins/qmldesigner/designercore/include/projectstorageids.h b/src/plugins/qmldesigner/designercore/include/projectstorageids.h
index 76f547eeb1..765f2c9c65 100644
--- a/src/plugins/qmldesigner/designercore/include/projectstorageids.h
+++ b/src/plugins/qmldesigner/designercore/include/projectstorageids.h
@@ -37,7 +37,7 @@ public:
constexpr explicit BasicId() = default;
- BasicId(const char *) = delete;
+ constexpr BasicId(const char *) = delete;
constexpr explicit BasicId(InternalIntergerType id)
: id{id}
diff --git a/src/plugins/qmldesigner/designercore/include/rewriterview.h b/src/plugins/qmldesigner/designercore/include/rewriterview.h
index ac251ef064..44e804f25d 100644
--- a/src/plugins/qmldesigner/designercore/include/rewriterview.h
+++ b/src/plugins/qmldesigner/designercore/include/rewriterview.h
@@ -177,6 +177,8 @@ public:
ModelNode getNodeForCanonicalIndex(int index);
+ void sanitizeModel();
+
signals:
void modelInterfaceProjectUpdated();
diff --git a/src/plugins/qmldesigner/designercore/metainfo/metainforeader.cpp b/src/plugins/qmldesigner/designercore/metainfo/metainforeader.cpp
index 28d8e02826..46ad1270e7 100644
--- a/src/plugins/qmldesigner/designercore/metainfo/metainforeader.cpp
+++ b/src/plugins/qmldesigner/designercore/metainfo/metainforeader.cpp
@@ -89,6 +89,7 @@ void MetaInfoReader::setQualifcation(const TypeName &qualification)
void MetaInfoReader::elementStart(const QString &name, const QmlJS::SourceLocation &nameLocation)
{
+ Q_UNUSED(nameLocation)
switch (parserState()) {
case ParsingDocument: setParserState(readDocument(name)); break;
case ParsingMetaInfo: setParserState(readMetaInfoRootElement(name)); break;
@@ -133,6 +134,8 @@ void MetaInfoReader::propertyDefinition(const QString &name,
const QVariant &value,
const QmlJS::SourceLocation &valueLocation)
{
+ Q_UNUSED(nameLocation)
+ Q_UNUSED(valueLocation)
switch (parserState()) {
case ParsingType: readTypeProperty(name, value); break;
case ParsingImports: readImportsProperty(name, value); break;
diff --git a/src/plugins/qmldesigner/designercore/metainfo/nodemetainfo.cpp b/src/plugins/qmldesigner/designercore/metainfo/nodemetainfo.cpp
index 33693210a9..97ff30850f 100644
--- a/src/plugins/qmldesigner/designercore/metainfo/nodemetainfo.cpp
+++ b/src/plugins/qmldesigner/designercore/metainfo/nodemetainfo.cpp
@@ -1505,6 +1505,8 @@ QVariant NodeMetaInfo::propertyCastedValue(const PropertyName &propertyName, con
return variant.toFloat();
} else if (typeName == "<cpp>.int") {
return variant.toInt();
+ } else if (typeName == "<cpp>.bool") {
+ return variant.toBool();
} else if (copyVariant.convert(typeId)) {
return copyVariant;
}
diff --git a/src/plugins/qmldesigner/designercore/model/import.cpp b/src/plugins/qmldesigner/designercore/model/import.cpp
index d895b07764..1c217bf47b 100644
--- a/src/plugins/qmldesigner/designercore/model/import.cpp
+++ b/src/plugins/qmldesigner/designercore/model/import.cpp
@@ -109,7 +109,7 @@ int Import::majorFromVersion(const QString &version)
return version.split('.').first().toInt();
}
-uint qHash(const Import &import)
+Utils::QHashValueType qHash(const Import &import)
{
return ::qHash(import.url()) ^ ::qHash(import.file()) ^ ::qHash(import.version()) ^ ::qHash(import.alias());
}
diff --git a/src/plugins/qmldesigner/designercore/model/qmlobjectnode.cpp b/src/plugins/qmldesigner/designercore/model/qmlobjectnode.cpp
index 55305c72d1..2445042fbb 100644
--- a/src/plugins/qmldesigner/designercore/model/qmlobjectnode.cpp
+++ b/src/plugins/qmldesigner/designercore/model/qmlobjectnode.cpp
@@ -332,7 +332,7 @@ static void removeStateOperationsForChildren(const QmlObjectNode &node)
stateOperation.modelNode().destroy(); //remove of belonging StatesOperations
}
- for (const QmlObjectNode &childNode : node.modelNode().directSubModelNodes()) {
+ for (const QmlObjectNode childNode : node.modelNode().directSubModelNodes()) {
removeStateOperationsForChildren(childNode);
}
}
diff --git a/src/plugins/qmldesigner/designercore/model/qmltimelinekeyframegroup.cpp b/src/plugins/qmldesigner/designercore/model/qmltimelinekeyframegroup.cpp
index 85eb51de44..924a4e0ee6 100644
--- a/src/plugins/qmldesigner/designercore/model/qmltimelinekeyframegroup.cpp
+++ b/src/plugins/qmldesigner/designercore/model/qmltimelinekeyframegroup.cpp
@@ -310,7 +310,7 @@ QList<QmlTimelineKeyframeGroup> QmlTimelineKeyframeGroup::allInvalidTimelineKeyf
QTC_ASSERT(view->rootModelNode().isValid(), return ret);
const auto groups = view->rootModelNode().subModelNodesOfType("QtQuick.Timeline.KeyframeGroup");
- for (const QmlTimelineKeyframeGroup &group : groups) {
+ for (const QmlTimelineKeyframeGroup group : groups) {
if (group.isDangling())
ret.append(group);
}
diff --git a/src/plugins/qmldesigner/designercore/model/rewriterview.cpp b/src/plugins/qmldesigner/designercore/model/rewriterview.cpp
index af066b81c2..e33c82b124 100644
--- a/src/plugins/qmldesigner/designercore/model/rewriterview.cpp
+++ b/src/plugins/qmldesigner/designercore/model/rewriterview.cpp
@@ -39,6 +39,8 @@
#include <modelnodepositionstorage.h>
#include <modelnode.h>
#include <nodeproperty.h>
+#include <qmlobjectnode.h>
+#include <qmltimelinekeyframegroup.h>
#ifndef QMLDESIGNER_TEST
#include <qmldesignerplugin.h>
@@ -57,6 +59,7 @@
#include <utility>
#include <vector>
+#include <algorithm>
using namespace QmlDesigner::Internal;
@@ -658,6 +661,36 @@ ModelNode RewriterView::getNodeForCanonicalIndex(int index)
return m_canonicalIntModelNode.value(index);
}
+void RewriterView::sanitizeModel()
+{
+ if (inErrorState())
+ return;
+
+ QmlObjectNode root = rootModelNode();
+
+ QTC_ASSERT(root.isValid(), return);
+
+ QList<ModelNode> danglingNodes;
+
+ const auto danglingStates = root.allInvalidStateOperations();
+ const auto danglingKeyframeGroups = QmlTimelineKeyframeGroup::allInvalidTimelineKeyframeGroups(this);
+
+ std::transform(danglingStates.begin(),
+ danglingStates.end(),
+ std::back_inserter(danglingNodes),
+ [](const auto &node) { return node.modelNode(); });
+
+ std::transform(danglingKeyframeGroups.begin(),
+ danglingKeyframeGroups.end(),
+ std::back_inserter(danglingNodes),
+ [](const auto &node) { return node.modelNode(); });
+
+ executeInTransaction("RewriterView::sanitizeModel", [&]() {
+ for (auto node : std::as_const(danglingNodes))
+ node.destroy();
+ });
+}
+
Internal::ModelNodePositionStorage *RewriterView::positionStorage() const
{
return m_positionStorage.data();
diff --git a/src/plugins/qmldesigner/designercore/projectstorage/projectstorage.h b/src/plugins/qmldesigner/designercore/projectstorage/projectstorage.h
index 2a428c6533..5df23b7385 100644
--- a/src/plugins/qmldesigner/designercore/projectstorage/projectstorage.h
+++ b/src/plugins/qmldesigner/designercore/projectstorage/projectstorage.h
@@ -28,6 +28,7 @@
#include "projectstorageexceptions.h"
#include "projectstorageinterface.h"
#include "sourcepathcachetypes.h"
+#include "storagecache.h"
#include <sqlitealgorithms.h>
#include <sqlitetable.h>
@@ -35,7 +36,9 @@
#include <utils/algorithm.h>
#include <utils/optional.h>
+#include <utils/set_algorithm.h>
+#include <algorithm>
#include <tuple>
namespace QmlDesigner {
@@ -53,65 +56,73 @@ public:
ProjectStorage(Database &database, bool isInitialized)
: database{database}
, initializer{database, isInitialized}
- {}
+ {
+ moduleCache.populate();
+ }
- void synchronize(Storage::Modules modules,
- Storage::Imports imports,
- Storage::Types types,
- SourceIds sourceIds,
- FileStatuses fileStatuses) override
+ void synchronize(Storage::SynchronizationPackage package) override
{
Sqlite::ImmediateTransaction transaction{database};
- std::vector<AliasPropertyDeclaration> insertedAliasPropertyDeclarations;
- std::vector<AliasPropertyDeclaration> updatedAliasPropertyDeclarations;
+ AliasPropertyDeclarations insertedAliasPropertyDeclarations;
+ AliasPropertyDeclarations updatedAliasPropertyDeclarations;
+
+ AliasPropertyDeclarations relinkableAliasPropertyDeclarations;
+ PropertyDeclarations relinkablePropertyDeclarations;
+ Prototypes relinkablePrototypes;
+ TypeIds deletedTypeIds;
TypeIds updatedTypeIds;
- updatedTypeIds.reserve(types.size());
+ updatedTypeIds.reserve(package.types.size());
TypeIds typeIdsToBeDeleted;
- auto sourceIdValues = Utils::transform<std::vector>(sourceIds, [](SourceId sourceId) {
+ auto sourceIdValues = Utils::transform<std::vector>(package.sourceIds, [](SourceId sourceId) {
return &sourceId;
});
std::sort(sourceIdValues.begin(), sourceIdValues.end());
- synchronizeFileStatuses(fileStatuses, sourceIdValues);
- synchronizeModules(modules, typeIdsToBeDeleted, sourceIdValues);
- synchronizeImports(imports, sourceIdValues);
- synchronizeTypes(types,
+ synchronizeFileStatuses(package.fileStatuses, sourceIdValues);
+ synchronizeImports(package.imports, sourceIdValues);
+ synchronizeTypes(package.types,
updatedTypeIds,
insertedAliasPropertyDeclarations,
- updatedAliasPropertyDeclarations);
-
- deleteNotUpdatedTypes(updatedTypeIds, sourceIdValues, typeIdsToBeDeleted);
+ updatedAliasPropertyDeclarations,
+ relinkableAliasPropertyDeclarations,
+ relinkablePropertyDeclarations,
+ relinkablePrototypes,
+ sourceIdValues);
+
+ deleteNotUpdatedTypes(updatedTypeIds,
+ sourceIdValues,
+ typeIdsToBeDeleted,
+ relinkableAliasPropertyDeclarations,
+ relinkablePropertyDeclarations,
+ relinkablePrototypes,
+ deletedTypeIds);
+
+ relink(relinkableAliasPropertyDeclarations,
+ relinkablePropertyDeclarations,
+ relinkablePrototypes,
+ deletedTypeIds);
linkAliases(insertedAliasPropertyDeclarations, updatedAliasPropertyDeclarations);
transaction.commit();
}
- ModuleId fetchModuleId(Utils::SmallStringView moduleName)
+ ModuleId moduleId(Utils::SmallStringView moduleName) override
{
- Sqlite::DeferredTransaction transaction{database};
-
- ModuleId moduleId = fetchModuleIdUnguarded(moduleName);
-
- transaction.commit();
-
- return moduleId;
+ return moduleCache.id(moduleName);
}
- ModuleIds fetchModuleIds(const Storage::Modules &modules)
+ Utils::SmallString moduleName(ModuleId moduleId)
{
- Sqlite::DeferredTransaction transaction{database};
-
- ModuleIds moduleIds = fetchModuleIdsUnguarded(modules);
-
- transaction.commit();
+ if (!moduleId)
+ throw ModuleDoesNotExists{};
- return moduleIds;
+ return moduleCache.value(moduleId);
}
PropertyDeclarationId fetchPropertyDeclarationByTypeIdAndName(TypeId typeId,
@@ -132,9 +143,9 @@ public:
static_cast<void *>(moduleIds.data()), static_cast<long long>(moduleIds.size()), name);
}
- TypeId fetchTypeIdByName(ModuleId moduleId, Utils::SmallStringView name)
+ TypeId fetchTypeIdByName(SourceId sourceId, Utils::SmallStringView name)
{
- return selectTypeIdByModuleIdAndNameStatement.template valueWithTransaction<TypeId>(&moduleId,
+ return selectTypeIdBySourceIdAndNameStatement.template valueWithTransaction<TypeId>(&sourceId,
name);
}
@@ -283,11 +294,6 @@ public:
return writeSourceId(sourceContextId, sourceName);
}
- auto fetchAllModules() const
- {
- return selectAllModulesStatement.template valuesWithTransaction<Storage::Module>(128);
- }
-
auto fetchAllFileStatuses() const
{
return selectAllFileStatusesStatement.template rangeWithTransaction<FileStatus>();
@@ -299,9 +305,79 @@ public:
&sourceId);
}
- SourceIds fetchSourceDependencieIds(SourceId sourceId) const override { return {}; }
+ Storage::ProjectDatas fetchProjectDatas(SourceId sourceId) const override
+ {
+ return Storage::ProjectDatas{};
+ }
private:
+ class ModuleStorageAdapter
+ {
+ public:
+ auto fetchId(const Utils::SmallStringView name) { return storage.fetchModuleId(name); }
+
+ auto fetchValue(ModuleId id) { return storage.fetchModuleName(id); }
+
+ auto fetchAll() { return storage.fetchAllModules(); }
+
+ ProjectStorage &storage;
+ };
+
+ class Module : public StorageCacheEntry<Utils::PathString, Utils::SmallStringView, ModuleId>
+ {
+ using Base = StorageCacheEntry<Utils::PathString, Utils::SmallStringView, ModuleId>;
+
+ public:
+ using Base::Base;
+
+ friend bool operator==(const Module &first, const Module &second)
+ {
+ return first.id == second.id && first.value == second.value;
+ }
+ };
+
+ friend ModuleStorageAdapter;
+
+ static bool moduleNameLess(Utils::SmallStringView first, Utils::SmallStringView second) noexcept
+ {
+ return Utils::reverseCompare(first, second) < 0;
+ }
+
+ using ModuleCache = StorageCache<Utils::PathString,
+ Utils::SmallStringView,
+ ModuleId,
+ ModuleStorageAdapter,
+ NonLockingMutex,
+ moduleNameLess,
+ Module>;
+
+ ModuleId fetchModuleId(Utils::SmallStringView moduleName)
+ {
+ Sqlite::DeferredTransaction transaction{database};
+
+ ModuleId moduleId = fetchModuleIdUnguarded(moduleName);
+
+ transaction.commit();
+
+ return moduleId;
+ }
+
+ auto fetchModuleName(ModuleId id)
+ {
+ Sqlite::DeferredTransaction transaction{database};
+
+ auto moduleName = fetchModuleNameUnguarded(id);
+
+ transaction.commit();
+
+ return moduleName;
+ }
+
+ auto fetchAllModules() const
+ {
+ return selectAllModulesStatement.template valuesWithTransaction<Module>(128);
+ }
+
class AliasPropertyDeclaration
{
public:
@@ -318,6 +394,13 @@ private:
, aliasPropertyDeclarationId{aliasPropertyDeclarationId}
{}
+ friend bool operator<(const AliasPropertyDeclaration &first,
+ const AliasPropertyDeclaration &second)
+ {
+ return std::tie(first.typeId, first.propertyDeclarationId)
+ < std::tie(second.typeId, second.propertyDeclarationId);
+ }
+
public:
TypeId typeId;
PropertyDeclarationId propertyDeclarationId;
@@ -326,6 +409,8 @@ private:
PropertyDeclarationId aliasPropertyDeclarationId;
};
+ using AliasPropertyDeclarations = std::vector<AliasPropertyDeclaration>;
+
class PropertyDeclaration
{
public:
@@ -345,12 +430,20 @@ private:
, importedTypeNameId{importedTypeNameId}
{}
+ friend bool operator<(const PropertyDeclaration &first, const PropertyDeclaration &second)
+ {
+ return std::tie(first.typeId, first.propertyDeclarationId)
+ < std::tie(second.typeId, second.propertyDeclarationId);
+ }
+
public:
TypeId typeId;
PropertyDeclarationId propertyDeclarationId;
ImportedTypeNameId importedTypeNameId;
};
+ using PropertyDeclarations = std::vector<PropertyDeclaration>;
+
class Prototype
{
public:
@@ -359,15 +452,58 @@ private:
, prototypeNameId{std::move(prototypeNameId)}
{}
+ friend bool operator<(Prototype first, Prototype second)
+ {
+ return first.typeId < second.typeId;
+ }
+
public:
TypeId typeId;
ImportedTypeNameId prototypeNameId;
};
+ using Prototypes = std::vector<Prototype>;
+
+ template<typename Type>
+ struct TypeCompare
+ {
+ bool operator()(const Type &type, TypeId typeId) { return type.typeId < typeId; };
+
+ bool operator()(TypeId typeId, const Type &type) { return typeId < type.typeId; };
+
+ bool operator()(const Type &first, const Type &second)
+ {
+ return first.typeId < second.typeId;
+ };
+ };
+
+ template<typename Property>
+ struct PropertyCompare
+ {
+ bool operator()(const Property &property, PropertyDeclarationId id)
+ {
+ return property.propertyDeclarationId < id;
+ };
+
+ bool operator()(PropertyDeclarationId id, const Property &property)
+ {
+ return id < property.propertyDeclarationId;
+ };
+
+ bool operator()(const Property &first, const Property &second)
+ {
+ return first.propertyDeclarationId < second.propertyDeclarationId;
+ };
+ };
+
void synchronizeTypes(Storage::Types &types,
TypeIds &updatedTypeIds,
- std::vector<AliasPropertyDeclaration> &insertedAliasPropertyDeclarations,
- std::vector<AliasPropertyDeclaration> &updatedAliasPropertyDeclarations)
+ AliasPropertyDeclarations &insertedAliasPropertyDeclarations,
+ AliasPropertyDeclarations &updatedAliasPropertyDeclarations,
+ AliasPropertyDeclarations &relinkableAliasPropertyDeclarations,
+ PropertyDeclarations &relinkablePropertyDeclarations,
+ Prototypes &relinkablePrototypes,
+ const std::vector<int> &sourceIdValues)
{
Storage::ExportedTypes exportedTypes;
exportedTypes.reserve(types.size() * 3);
@@ -381,16 +517,19 @@ private:
extractExportedTypes(typeId, type, exportedTypes);
}
- synchronizeExportedTypes(updatedTypeIds, exportedTypes);
+ synchronizeExportedTypes(sourceIdValues,
+ updatedTypeIds,
+ exportedTypes,
+ relinkableAliasPropertyDeclarations,
+ relinkablePropertyDeclarations,
+ relinkablePrototypes);
- for (auto &&type : types)
- syncPrototypes(type);
-
- for (auto &&type : types)
- resetRemovedAliasPropertyDeclarationsToNull(type.typeId, type.propertyDeclarations);
-
- for (auto &&type : types)
- syncDeclarations(type, insertedAliasPropertyDeclarations, updatedAliasPropertyDeclarations);
+ syncPrototypes(types, relinkablePrototypes);
+ resetRemovedAliasPropertyDeclarationsToNull(types, relinkableAliasPropertyDeclarations);
+ syncDeclarations(types,
+ insertedAliasPropertyDeclarations,
+ updatedAliasPropertyDeclarations,
+ relinkablePropertyDeclarations);
}
void synchronizeFileStatuses(FileStatuses &fileStatuses, const std::vector<int> &sourceIdValues)
@@ -428,43 +567,10 @@ private:
Sqlite::insertUpdateDelete(range, fileStatuses, compareKey, insert, update, remove);
}
- void synchronizeModules(Storage::Modules &modules,
- TypeIds &typeIdsToBeDeleted,
- const std::vector<int> &moduleIdValues)
- {
- auto compareKey = [](auto &&first, auto &&second) {
- return first.sourceId.id - second.sourceId.id;
- };
-
- std::sort(modules.begin(), modules.end(), [&](auto &&first, auto &&second) {
- return compareKey(first, second) < 0;
- });
-
- auto range = selectModulesForIdsStatement.template range<Storage::ModuleView>(
- Utils::span(moduleIdValues));
-
- auto insert = [&](Storage::Module &module) {
- insertModuleStatement.write(module.name, &module.sourceId);
- };
-
- auto update = [&](const Storage::ModuleView &moduleView, Storage::Module &module) {
- if (moduleView.name != module.name)
- updateModuleStatement.write(&moduleView.sourceId, module.name);
- };
-
- auto remove = [&](const Storage::ModuleView &moduleView) {
- deleteModuleStatement.write(&moduleView.sourceId);
- selectTypeIdsForModuleIdStatement.readTo(typeIdsToBeDeleted, &moduleView.sourceId);
- };
-
- Sqlite::insertUpdateDelete(range, modules, compareKey, insert, update, remove);
- }
-
void synchronizeImports(Storage::Imports &imports, std::vector<int> &sourceIdValues)
{
deleteDocumentImportsForDeletedDocuments(imports, sourceIdValues);
- addModuleIdToImports(imports);
synchronizeDocumentImports(imports, sourceIdValues);
}
@@ -487,50 +593,28 @@ private:
deleteDocumentImportsWithSourceIdsStatement.write(Utils::span{documentSourceIdsToBeDeleted});
}
- void synchronizeModulesAndUpdatesModuleIds(Storage::Modules &modules,
- TypeIds &typeIdsToBeDeleted,
- const std::vector<int> &moduleIds)
+ ModuleId fetchModuleIdUnguarded(Utils::SmallStringView name) const
{
- auto compareKey = [](auto &&first, auto &&second) {
- return first.sourceId.id - second.sourceId.id;
- };
-
- std::sort(modules.begin(), modules.end(), [&](auto &&first, auto &&second) {
- return compareKey(first, second) < 0;
- });
-
- auto range = selectModulesForIdsStatement.template range<Storage::ModuleView>(
- Utils::span(moduleIds));
-
- auto insert = [&](Storage::Module &module) {
- insertModuleStatement.write(module.name, &module.sourceId);
- };
-
- auto update = [&](const Storage::ModuleView &moduleView, Storage::Module &module) {
- if (moduleView.name != module.name)
- updateModuleStatement.write(&moduleView.sourceId, module.name);
- };
+ auto moduleId = selectModuleIdByNameStatement.template value<ModuleId>(name);
- auto remove = [&](const Storage::ModuleView &moduleView) {
- deleteModuleStatement.write(&moduleView.sourceId);
- selectTypeIdsForModuleIdStatement.readTo(typeIdsToBeDeleted, &moduleView.sourceId);
- };
+ if (moduleId)
+ return moduleId;
- Sqlite::insertUpdateDelete(range, modules, compareKey, insert, update, remove);
+ return insertModuleNameStatement.template value<ModuleId>(name);
}
- ModuleId fetchModuleIdUnguarded(const Storage::Module &module) const
+ auto fetchModuleNameUnguarded(ModuleId id) const
{
- return fetchModuleIdUnguarded(module.name);
- }
+ auto moduleName = selectModuleNameStatement.template value<Utils::PathString>(&id);
- ModuleId fetchModuleIdUnguarded(Utils::SmallStringView name) const
- {
- return selectModuleIdByNameStatement.template value<ModuleId>(name);
+ if (moduleName.empty())
+ throw ModuleDoesNotExists{};
+
+ return moduleName;
}
void handleAliasPropertyDeclarationsWithPropertyType(
- TypeId typeId, std::vector<AliasPropertyDeclaration> &relinkableAliasPropertyDeclarations)
+ TypeId typeId, AliasPropertyDeclarations &relinkableAliasPropertyDeclarations)
{
auto callback = [&](long long typeId,
long long propertyDeclarationId,
@@ -555,8 +639,7 @@ private:
}
void prepareLinkingOfAliasPropertiesDeclarationsWithAliasId(
- PropertyDeclarationId aliasId,
- std::vector<AliasPropertyDeclaration> &relinkableAliasPropertyDeclarations)
+ PropertyDeclarationId aliasId, AliasPropertyDeclarations &relinkableAliasPropertyDeclarations)
{
auto callback = [&](long long propertyDeclarationId,
long long propertyImportedTypeNameId,
@@ -578,14 +661,14 @@ private:
&aliasId);
}
- void handlePropertyDeclarationWithPropertyType(
- TypeId typeId, std::vector<PropertyDeclaration> &relinkablePropertyDeclarations)
+ void handlePropertyDeclarationWithPropertyType(TypeId typeId,
+ PropertyDeclarations &relinkablePropertyDeclarations)
{
updatesPropertyDeclarationPropertyTypeToNullStatement.readTo(relinkablePropertyDeclarations,
&typeId);
}
- void handlePrototypes(TypeId prototypeId, std::vector<Prototype> &relinkablePrototypes)
+ void handlePrototypes(TypeId prototypeId, Prototypes &relinkablePrototypes)
{
auto callback = [&](long long typeId, long long prototypeNameId) {
relinkablePrototypes.emplace_back(TypeId{typeId}, ImportedTypeNameId{prototypeNameId});
@@ -597,9 +680,9 @@ private:
}
void deleteType(TypeId typeId,
- std::vector<AliasPropertyDeclaration> &relinkableAliasPropertyDeclarations,
- std::vector<PropertyDeclaration> &relinkablePropertyDeclarations,
- std::vector<Prototype> &relinkablePrototypes)
+ AliasPropertyDeclarations &relinkableAliasPropertyDeclarations,
+ PropertyDeclarations &relinkablePropertyDeclarations,
+ Prototypes &relinkablePrototypes)
{
handlePropertyDeclarationWithPropertyType(typeId, relinkablePropertyDeclarations);
handleAliasPropertyDeclarationsWithPropertyType(typeId, relinkableAliasPropertyDeclarations);
@@ -612,72 +695,85 @@ private:
deleteTypeStatement.write(&typeId);
}
- void relinkAliasPropertyDeclarations(
- const std::vector<AliasPropertyDeclaration> &aliasPropertyDeclarations,
- const TypeIds &deletedTypeIds)
+ void relinkAliasPropertyDeclarations(AliasPropertyDeclarations &aliasPropertyDeclarations,
+ const TypeIds &deletedTypeIds)
{
- for (const AliasPropertyDeclaration &alias : aliasPropertyDeclarations) {
- if (std::binary_search(deletedTypeIds.begin(), deletedTypeIds.end(), alias.typeId))
- continue;
+ std::sort(aliasPropertyDeclarations.begin(), aliasPropertyDeclarations.end());
- auto typeId = fetchTypeId(alias.aliasImportedTypeNameId);
+ Utils::set_greedy_difference(
+ aliasPropertyDeclarations.cbegin(),
+ aliasPropertyDeclarations.cend(),
+ deletedTypeIds.begin(),
+ deletedTypeIds.end(),
+ [&](const AliasPropertyDeclaration &alias) {
+ auto typeId = fetchTypeId(alias.aliasImportedTypeNameId);
- if (!typeId)
- throw TypeNameDoesNotExists{};
+ if (!typeId)
+ throw TypeNameDoesNotExists{};
- auto [propertyTypeId, aliasId, propertyTraits] = fetchPropertyDeclarationByTypeIdAndNameUngarded(
- typeId, alias.aliasPropertyName);
+ auto [propertyTypeId, aliasId, propertyTraits] = fetchPropertyDeclarationByTypeIdAndNameUngarded(
+ typeId, alias.aliasPropertyName);
- updatePropertyDeclarationWithAliasAndTypeStatement.write(&alias.propertyDeclarationId,
- &propertyTypeId,
- propertyTraits,
- &alias.aliasImportedTypeNameId,
- &aliasId);
- }
+ updatePropertyDeclarationWithAliasAndTypeStatement.write(&alias.propertyDeclarationId,
+ &propertyTypeId,
+ propertyTraits,
+ &alias.aliasImportedTypeNameId,
+ &aliasId);
+ },
+ TypeCompare<AliasPropertyDeclaration>{});
}
- void relinkPropertyDeclarations(const std::vector<PropertyDeclaration> &relinkablePropertyDeclaration,
+ void relinkPropertyDeclarations(PropertyDeclarations &relinkablePropertyDeclaration,
const TypeIds &deletedTypeIds)
{
- for (const PropertyDeclaration &property : relinkablePropertyDeclaration) {
- if (std::binary_search(deletedTypeIds.begin(), deletedTypeIds.end(), property.typeId))
- continue;
+ std::sort(relinkablePropertyDeclaration.begin(), relinkablePropertyDeclaration.end());
- TypeId propertyTypeId = fetchTypeId(property.importedTypeNameId);
+ Utils::set_greedy_difference(
+ relinkablePropertyDeclaration.cbegin(),
+ relinkablePropertyDeclaration.cend(),
+ deletedTypeIds.begin(),
+ deletedTypeIds.end(),
+ [&](const PropertyDeclaration &property) {
+ TypeId propertyTypeId = fetchTypeId(property.importedTypeNameId);
- if (!propertyTypeId)
- throw TypeNameDoesNotExists{};
+ if (!propertyTypeId)
+ throw TypeNameDoesNotExists{};
- updatePropertyDeclarationTypeStatement.write(&property.propertyDeclarationId,
- &propertyTypeId);
- }
+ updatePropertyDeclarationTypeStatement.write(&property.propertyDeclarationId,
+ &propertyTypeId);
+ },
+ TypeCompare<PropertyDeclaration>{});
}
- void relinkPrototypes(std::vector<Prototype> relinkablePrototypes, const TypeIds &deletedTypeIds)
+ void relinkPrototypes(Prototypes &relinkablePrototypes, const TypeIds &deletedTypeIds)
{
- for (const Prototype &prototype : relinkablePrototypes) {
- if (std::binary_search(deletedTypeIds.begin(), deletedTypeIds.end(), prototype.typeId))
- continue;
+ std::sort(relinkablePrototypes.begin(), relinkablePrototypes.end());
- TypeId prototypeId = fetchTypeId(prototype.prototypeNameId);
+ Utils::set_greedy_difference(
+ relinkablePrototypes.cbegin(),
+ relinkablePrototypes.cend(),
+ deletedTypeIds.begin(),
+ deletedTypeIds.end(),
+ [&](const Prototype &prototype) {
+ TypeId prototypeId = fetchTypeId(prototype.prototypeNameId);
- if (!prototypeId)
- throw TypeNameDoesNotExists{};
+ if (!prototypeId)
+ throw TypeNameDoesNotExists{};
- updateTypePrototypeStatement.write(&prototype.typeId, &prototypeId);
- checkForPrototypeChainCycle(prototype.typeId);
- }
+ updateTypePrototypeStatement.write(&prototype.typeId, &prototypeId);
+ checkForPrototypeChainCycle(prototype.typeId);
+ },
+ TypeCompare<Prototype>{});
}
void deleteNotUpdatedTypes(const TypeIds &updatedTypeIds,
const std::vector<int> &sourceIdValues,
- const TypeIds &typeIdsToBeDeleted)
+ const TypeIds &typeIdsToBeDeleted,
+ AliasPropertyDeclarations &relinkableAliasPropertyDeclarations,
+ PropertyDeclarations &relinkablePropertyDeclarations,
+ Prototypes &relinkablePrototypes,
+ TypeIds &deletedTypeIds)
{
- std::vector<AliasPropertyDeclaration> relinkableAliasPropertyDeclarations;
- std::vector<PropertyDeclaration> relinkablePropertyDeclarations;
- std::vector<Prototype> relinkablePrototypes;
- TypeIds deletedTypeIds;
-
auto updatedTypeIdValues = Utils::transform<std::vector>(updatedTypeIds, [](TypeId typeId) {
return &typeId;
});
@@ -696,7 +792,13 @@ private:
Utils::span(updatedTypeIdValues));
for (TypeId typeIdToBeDeleted : typeIdsToBeDeleted)
callback(&typeIdToBeDeleted);
+ }
+ void relink(AliasPropertyDeclarations &relinkableAliasPropertyDeclarations,
+ PropertyDeclarations &relinkablePropertyDeclarations,
+ Prototypes &relinkablePrototypes,
+ TypeIds &deletedTypeIds)
+ {
std::sort(deletedTypeIds.begin(), deletedTypeIds.end());
relinkPrototypes(relinkablePrototypes, deletedTypeIds);
@@ -704,7 +806,7 @@ private:
relinkAliasPropertyDeclarations(relinkableAliasPropertyDeclarations, deletedTypeIds);
}
- void linkAliasPropertyDeclarationAliasIds(const std::vector<AliasPropertyDeclaration> &aliasDeclarations)
+ void linkAliasPropertyDeclarationAliasIds(const AliasPropertyDeclarations &aliasDeclarations)
{
for (const auto &aliasDeclaration : aliasDeclarations) {
auto aliasTypeId = fetchTypeId(aliasDeclaration.aliasImportedTypeNameId);
@@ -722,7 +824,7 @@ private:
}
}
- void updateAliasPropertyDeclarationValues(const std::vector<AliasPropertyDeclaration> &aliasDeclarations)
+ void updateAliasPropertyDeclarationValues(const AliasPropertyDeclarations &aliasDeclarations)
{
for (const auto &aliasDeclaration : aliasDeclarations) {
updatetPropertiesDeclarationValuesOfAliasStatement.write(
@@ -732,14 +834,14 @@ private:
}
}
- void checkAliasPropertyDeclarationCycles(const std::vector<AliasPropertyDeclaration> &aliasDeclarations)
+ void checkAliasPropertyDeclarationCycles(const AliasPropertyDeclarations &aliasDeclarations)
{
for (const auto &aliasDeclaration : aliasDeclarations)
checkForAliasChainCycle(aliasDeclaration.propertyDeclarationId);
}
- void linkAliases(const std::vector<AliasPropertyDeclaration> &insertedAliasPropertyDeclarations,
- const std::vector<AliasPropertyDeclaration> &updatedAliasPropertyDeclarations)
+ void linkAliases(const AliasPropertyDeclarations &insertedAliasPropertyDeclarations,
+ const AliasPropertyDeclarations &updatedAliasPropertyDeclarations)
{
linkAliasPropertyDeclarationAliasIds(insertedAliasPropertyDeclarations);
linkAliasPropertyDeclarationAliasIds(updatedAliasPropertyDeclarations);
@@ -751,16 +853,25 @@ private:
updateAliasPropertyDeclarationValues(updatedAliasPropertyDeclarations);
}
- void synchronizeExportedTypes(const TypeIds &typeIds, Storage::ExportedTypes &exportedTypes)
+ void synchronizeExportedTypes(const std::vector<int> &sourceIdValues,
+ const TypeIds &updatedTypeIds,
+ Storage::ExportedTypes &exportedTypes,
+ AliasPropertyDeclarations &relinkableAliasPropertyDeclarations,
+ PropertyDeclarations &relinkablePropertyDeclarations,
+ Prototypes &relinkablePrototypes)
{
std::sort(exportedTypes.begin(), exportedTypes.end(), [](auto &&first, auto &&second) {
return std::tie(first.moduleId, first.name, first.version)
< std::tie(second.moduleId, second.name, second.version);
});
- auto range = selectExportedTypesForTypeIdStatement.template range<Storage::ExportedTypeView>(
- const_cast<void *>(static_cast<const void *>(typeIds.data())),
- static_cast<long long>(typeIds.size()));
+ Utils::span typeIdValues{static_cast<const TypeIds::value_type::DatabaseType *>(
+ &updatedTypeIds.data()->id),
+ updatedTypeIds.size()};
+
+ auto range = selectExportedTypesForSourceIdsStatement
+ .template range<Storage::ExportedTypeView>(Utils::span{sourceIdValues},
+ typeIdValues);
auto compareKey = [](const Storage::ExportedTypeView &view,
const Storage::ExportedType &type) -> long long {
@@ -780,53 +891,55 @@ private:
};
auto insert = [&](const Storage::ExportedType &type) {
- if (type.version) {
- upsertExportedTypeNamesWithVersionStatement.write(&type.moduleId,
- type.name,
- static_cast<long long>(
- Storage::TypeNameKind::Exported),
- type.version.major.value,
- type.version.minor.value,
- &type.typeId);
-
- } else if (type.version.major) {
- upsertExportedTypeNamesWithMajorVersionStatement
- .write(&type.moduleId,
- type.name,
- static_cast<long long>(Storage::TypeNameKind::Exported),
- type.version.major.value,
- &type.typeId);
- } else {
- upsertExportedTypeNamesWithoutVersionStatement
- .write(&type.moduleId,
- type.name,
- static_cast<long long>(Storage::TypeNameKind::Exported),
- &type.typeId);
+ if (!type.moduleId)
+ throw QmlDesigner::ModuleDoesNotExists{};
+
+ try {
+ if (type.version) {
+ insertExportedTypeNamesWithVersionStatement.write(&type.moduleId,
+ type.name,
+ type.version.major.value,
+ type.version.minor.value,
+ &type.typeId);
+
+ } else if (type.version.major) {
+ insertExportedTypeNamesWithMajorVersionStatement.write(&type.moduleId,
+ type.name,
+ type.version.major.value,
+ &type.typeId);
+ } else {
+ insertExportedTypeNamesWithoutVersionStatement.write(&type.moduleId,
+ type.name,
+ &type.typeId);
+ }
+ } catch (const Sqlite::ConstraintPreventsModification &) {
+ throw QmlDesigner::ModuleDoesNotExists{};
}
};
auto update = [&](const Storage::ExportedTypeView &view, const Storage::ExportedType &type) {
- if (view.typeId != type.typeId)
+ if (view.typeId != type.typeId) {
+ handlePropertyDeclarationWithPropertyType(view.typeId, relinkablePropertyDeclarations);
+ handleAliasPropertyDeclarationsWithPropertyType(view.typeId,
+ relinkableAliasPropertyDeclarations);
+ handlePrototypes(view.typeId, relinkablePrototypes);
updateExportedTypeNameTypeIdStatement.write(&view.exportedTypeNameId, &type.typeId);
+ }
};
auto remove = [&](const Storage::ExportedTypeView &view) {
+ handlePropertyDeclarationWithPropertyType(view.typeId, relinkablePropertyDeclarations);
+ handleAliasPropertyDeclarationsWithPropertyType(view.typeId,
+ relinkableAliasPropertyDeclarations);
+ handlePrototypes(view.typeId, relinkablePrototypes);
deleteExportedTypeNameStatement.write(&view.exportedTypeNameId);
};
Sqlite::insertUpdateDelete(range, exportedTypes, compareKey, insert, update, remove);
}
- void upsertNativeType(ModuleId moduleId, Utils::SmallStringView name, TypeId typeId)
- {
- upsertExportedTypeNameStatement.write(&moduleId,
- name,
- static_cast<long long>(Storage::TypeNameKind::Native),
- &typeId);
- }
-
void synchronizePropertyDeclarationsInsertAlias(
- std::vector<AliasPropertyDeclaration> &insertedAliasPropertyDeclarations,
+ AliasPropertyDeclarations &insertedAliasPropertyDeclarations,
const Storage::PropertyDeclaration &value,
SourceId sourceId,
TypeId typeId)
@@ -872,7 +985,7 @@ private:
}
void synchronizePropertyDeclarationsUpdateAlias(
- std::vector<AliasPropertyDeclaration> &updatedAliasPropertyDeclarations,
+ AliasPropertyDeclarations &updatedAliasPropertyDeclarations,
const Storage::PropertyDeclarationView &view,
const Storage::PropertyDeclaration &value,
SourceId sourceId)
@@ -887,7 +1000,8 @@ private:
void synchronizePropertyDeclarationsUpdateProperty(const Storage::PropertyDeclarationView &view,
const Storage::PropertyDeclaration &value,
- SourceId sourceId)
+ SourceId sourceId,
+ PropertyDeclarationIds &propertyDeclarationIds)
{
auto propertyImportedTypeNameId = fetchImportedTypeNameId(value.typeName, sourceId);
@@ -906,14 +1020,15 @@ private:
&propertyImportedTypeNameId);
updatePropertyAliasDeclarationRecursivelyWithTypeAndTraitsStatement
.write(&view.id, &propertyTypeId, static_cast<int>(value.traits));
+ propertyDeclarationIds.push_back(view.id);
}
- void synchronizePropertyDeclarations(
- TypeId typeId,
- Storage::PropertyDeclarations &propertyDeclarations,
- SourceId sourceId,
- std::vector<AliasPropertyDeclaration> &insertedAliasPropertyDeclarations,
- std::vector<AliasPropertyDeclaration> &updatedAliasPropertyDeclarations)
+ void synchronizePropertyDeclarations(TypeId typeId,
+ Storage::PropertyDeclarations &propertyDeclarations,
+ SourceId sourceId,
+ AliasPropertyDeclarations &insertedAliasPropertyDeclarations,
+ AliasPropertyDeclarations &updatedAliasPropertyDeclarations,
+ PropertyDeclarationIds &propertyDeclarationIds)
{
std::sort(propertyDeclarations.begin(),
propertyDeclarations.end(),
@@ -947,8 +1062,12 @@ private:
view,
value,
sourceId);
+ propertyDeclarationIds.push_back(view.id);
} else {
- synchronizePropertyDeclarationsUpdateProperty(view, value, sourceId);
+ synchronizePropertyDeclarationsUpdateProperty(view,
+ value,
+ sourceId,
+ propertyDeclarationIds);
}
};
@@ -962,14 +1081,20 @@ private:
}
deletePropertyDeclarationStatement.write(&view.id);
+ propertyDeclarationIds.push_back(view.id);
};
Sqlite::insertUpdateDelete(range, propertyDeclarations, compareKey, insert, update, remove);
}
- void resetRemovedAliasPropertyDeclarationsToNull(TypeId typeId,
- Storage::PropertyDeclarations &aliasDeclarations)
+ void resetRemovedAliasPropertyDeclarationsToNull(Storage::Type &type,
+ PropertyDeclarationIds &propertyDeclarationIds)
{
+ if (type.changeLevel == Storage::ChangeLevel::Minimal)
+ return;
+
+ Storage::PropertyDeclarations &aliasDeclarations = type.propertyDeclarations;
+
class AliasPropertyDeclarationView
{
public:
@@ -992,7 +1117,7 @@ private:
});
auto range = selectPropertyDeclarationsWithAliasForTypeIdStatement
- .template range<AliasPropertyDeclarationView>(&typeId);
+ .template range<AliasPropertyDeclarationView>(&type.typeId);
auto compareKey = [](const AliasPropertyDeclarationView &view,
const Storage::PropertyDeclaration &value) {
@@ -1006,29 +1131,24 @@ private:
auto remove = [&](const AliasPropertyDeclarationView &view) {
updatePropertyDeclarationAliasIdToNullStatement.write(&view.id);
+ propertyDeclarationIds.push_back(view.id);
};
Sqlite::insertUpdateDelete(range, aliasDeclarations, compareKey, insert, update, remove);
}
- ModuleIds fetchModuleIdsUnguarded(const Storage::Modules &modules)
+ void resetRemovedAliasPropertyDeclarationsToNull(
+ Storage::Types &types, AliasPropertyDeclarations &relinkableAliasPropertyDeclarations)
{
- ModuleIds moduleIds;
- moduleIds.reserve(moduleIds.size());
+ PropertyDeclarationIds propertyDeclarationIds;
+ propertyDeclarationIds.reserve(types.size());
- for (auto &&module : modules)
- moduleIds.push_back(fetchModuleIdUnguarded(module));
+ for (auto &&type : types)
+ resetRemovedAliasPropertyDeclarationsToNull(type, propertyDeclarationIds);
- return moduleIds;
- }
-
- void addModuleIdToImports(Storage::Imports &imports)
- {
- for (Storage::Import &import : imports) {
- import.moduleId = fetchModuleIdUnguarded(import.name);
- if (!import.moduleId)
- throw ModuleDoesNotExists{};
- }
+ removeRelinkableEntries(relinkableAliasPropertyDeclarations,
+ propertyDeclarationIds,
+ PropertyCompare<AliasPropertyDeclaration>{});
}
void synchronizeDocumentImports(Storage::Imports &imports, const std::vector<int> &sourceIdValues)
@@ -1096,7 +1216,7 @@ private:
json.append(parameter.name);
json.append("\",\"tn\":\"");
json.append(parameter.typeName);
- if (parameter.traits == Storage::PropertyDeclarationTraits::Non) {
+ if (parameter.traits == Storage::PropertyDeclarationTraits::None) {
json.append("\"}");
} else {
json.append("\",\"tr\":");
@@ -1257,60 +1377,88 @@ private:
Storage::ExportedTypes &exportedTypes)
{
for (const auto &exportedType : type.exportedTypes)
- exportedTypes.emplace_back(exportedType.name, exportedType.version, typeId, type.moduleId);
+ exportedTypes.emplace_back(exportedType.name,
+ exportedType.version,
+ typeId,
+ exportedType.moduleId);
}
- struct ModuleAndTypeId
- {
- ModuleAndTypeId() = default;
- ModuleAndTypeId(int moduleId, long long typeId)
- : moduleId{moduleId}
- , typeId{typeId}
- {}
-
- ModuleId moduleId;
- TypeId typeId;
- };
-
TypeId declareType(Storage::Type &type)
{
- if (!type.moduleId && type.typeName.isEmpty()) {
- auto [moduleId, typeId] = selectModuleAndTypeIdBySourceIdStatement
- .template value<ModuleAndTypeId>(&type.sourceId);
- type.typeId = typeId;
- type.moduleId = moduleId;
+ if (type.typeName.isEmpty()) {
+ type.typeId = selectTypeIdBySourceIdStatement.template value<TypeId>(&type.sourceId);
+
return type.typeId;
}
- if (!type.moduleId)
- throw ModuleDoesNotExists{};
-
- type.typeId = upsertTypeStatement.template value<TypeId>(&type.moduleId,
+ type.typeId = upsertTypeStatement.template value<TypeId>(&type.sourceId,
type.typeName,
- static_cast<int>(type.accessSemantics),
- &type.sourceId);
+ static_cast<int>(
+ type.accessSemantics));
if (!type.typeId)
- type.typeId = selectTypeIdByModuleIdAndNameStatement.template value<TypeId>(&type.moduleId,
+ type.typeId = selectTypeIdBySourceIdAndNameStatement.template value<TypeId>(&type.sourceId,
type.typeName);
- upsertNativeType(type.moduleId, type.typeName, type.typeId);
return type.typeId;
}
void syncDeclarations(Storage::Type &type,
- std::vector<AliasPropertyDeclaration> &insertedAliasPropertyDeclarations,
- std::vector<AliasPropertyDeclaration> &updatedAliasPropertyDeclarations)
+ AliasPropertyDeclarations &insertedAliasPropertyDeclarations,
+ AliasPropertyDeclarations &updatedAliasPropertyDeclarations,
+ PropertyDeclarationIds &propertyDeclarationIds)
{
- auto typeId = type.typeId;
- synchronizePropertyDeclarations(typeId,
+ if (type.changeLevel == Storage::ChangeLevel::Minimal)
+ return;
+
+ synchronizePropertyDeclarations(type.typeId,
type.propertyDeclarations,
type.sourceId,
insertedAliasPropertyDeclarations,
- updatedAliasPropertyDeclarations);
- synchronizeFunctionDeclarations(typeId, type.functionDeclarations);
- synchronizeSignalDeclarations(typeId, type.signalDeclarations);
- synchronizeEnumerationDeclarations(typeId, type.enumerationDeclarations);
+ updatedAliasPropertyDeclarations,
+ propertyDeclarationIds);
+ synchronizeFunctionDeclarations(type.typeId, type.functionDeclarations);
+ synchronizeSignalDeclarations(type.typeId, type.signalDeclarations);
+ synchronizeEnumerationDeclarations(type.typeId, type.enumerationDeclarations);
+ }
+
+ template<typename Relinkable, typename Ids, typename Compare>
+ void removeRelinkableEntries(std::vector<Relinkable> &relinkables, Ids &ids, Compare compare)
+ {
+ std::vector<Relinkable> newRelinkables;
+ newRelinkables.reserve(relinkables.size());
+
+ std::sort(ids.begin(), ids.end());
+ std::sort(relinkables.begin(), relinkables.end(), compare);
+
+ Utils::set_greedy_difference(
+ relinkables.begin(),
+ relinkables.end(),
+ ids.cbegin(),
+ ids.cend(),
+ [&](Relinkable &entry) { newRelinkables.push_back(std::move(entry)); },
+ compare);
+
+ relinkables = std::move(newRelinkables);
+ }
+
+ void syncDeclarations(Storage::Types &types,
+ AliasPropertyDeclarations &insertedAliasPropertyDeclarations,
+ AliasPropertyDeclarations &updatedAliasPropertyDeclarations,
+ PropertyDeclarations &relinkablePropertyDeclarations)
+ {
+ PropertyDeclarationIds propertyDeclarationIds;
+ propertyDeclarationIds.reserve(types.size() * 10);
+
+ for (auto &&type : types)
+ syncDeclarations(type,
+ insertedAliasPropertyDeclarations,
+ updatedAliasPropertyDeclarations,
+ propertyDeclarationIds);
+
+ removeRelinkableEntries(relinkablePropertyDeclarations,
+ propertyDeclarationIds,
+ PropertyCompare<PropertyDeclaration>{});
}
void checkForPrototypeChainCycle(TypeId typeId) const
@@ -1338,7 +1486,7 @@ private:
&propertyDeclarationId);
}
- void syncPrototypes(Storage::Type &type)
+ void syncPrototype(Storage::Type &type, TypeIds &typeIds)
{
if (type.changeLevel == Storage::ChangeLevel::Minimal)
return;
@@ -1358,22 +1506,35 @@ private:
updatePrototypeStatement.write(&type.typeId, &prototypeId, &prototypeTypeNameId);
checkForPrototypeChainCycle(type.typeId);
}
+
+ typeIds.push_back(type.typeId);
+ }
+
+ void syncPrototypes(Storage::Types &types, Prototypes &relinkablePrototypes)
+ {
+ TypeIds typeIds;
+ typeIds.reserve(types.size());
+
+ for (auto &type : types)
+ syncPrototype(type, typeIds);
+
+ removeRelinkableEntries(relinkablePrototypes, typeIds, TypeCompare<Prototype>{});
}
ImportId fetchImportId(SourceId sourceId, const Storage::Import &import) const
{
if (import.version) {
- return selectImportIdBySourceIdAndImportNameAndVersionStatement.template value<ImportId>(
- &sourceId, import.name, import.version.major.value, import.version.minor.value);
+ return selectImportIdBySourceIdAndModuleIdAndVersionStatement.template value<ImportId>(
+ &sourceId, &import.moduleId, import.version.major.value, import.version.minor.value);
}
if (import.version.major) {
- return selectImportIdBySourceIdAndImportNameAndMajorVersionStatement
- .template value<ImportId>(&sourceId, import.name, import.version.major.value);
+ return selectImportIdBySourceIdAndModuleIdAndMajorVersionStatement
+ .template value<ImportId>(&sourceId, &import.moduleId, import.version.major.value);
}
- return selectImportIdBySourceIdAndImportNameStatement.template value<ImportId>(&sourceId,
- import.name);
+ return selectImportIdBySourceIdAndModuleIdStatement.template value<ImportId>(&sourceId,
+ &import.moduleId);
}
ImportedTypeNameId fetchImportedTypeNameId(const Storage::ImportedTypeName &name, SourceId sourceId)
@@ -1440,9 +1601,6 @@ private:
&typeNameId);
}
- if (kind == Storage::TypeNameKind::Native)
- return selectTypeIdForNativeTypeNameNamesStatement.template value<TypeId>(&typeNameId);
-
return selectTypeIdForImportedTypeNameNamesStatement.template value<TypeId>(&typeNameId);
}
@@ -1649,21 +1807,16 @@ private:
typesTable.setUseIfNotExists(true);
typesTable.setName("types");
typesTable.addColumn("typeId", Sqlite::ColumnType::Integer, {Sqlite::PrimaryKey{}});
- auto &moduleIdColumn = typesTable.addForeignKeyColumn("moduleId",
- foreignModuleIdColumn,
- Sqlite::ForeignKeyAction::NoAction,
- Sqlite::ForeignKeyAction::NoAction,
- Sqlite::Enforment::Deferred);
+ auto &sourceIdColumn = typesTable.addColumn("sourceId");
auto &typesNameColumn = typesTable.addColumn("name");
typesTable.addColumn("accessSemantics");
- typesTable.addColumn("sourceId");
typesTable.addForeignKeyColumn("prototypeId",
typesTable,
Sqlite::ForeignKeyAction::NoAction,
Sqlite::ForeignKeyAction::Restrict);
typesTable.addColumn("prototypeNameId");
- typesTable.addUniqueIndex({moduleIdColumn, typesNameColumn});
+ typesTable.addUniqueIndex({sourceIdColumn, typesNameColumn});
typesTable.initialize(database);
@@ -1706,23 +1859,20 @@ private:
auto &moduleIdColumn = table.addForeignKeyColumn("moduleId",
foreignModuleIdColumn,
Sqlite::ForeignKeyAction::NoAction,
- Sqlite::ForeignKeyAction::NoAction,
- Sqlite::Enforment::Deferred);
+ Sqlite::ForeignKeyAction::NoAction);
auto &nameColumn = table.addColumn("name");
- auto &kindColumn = table.addColumn("kind");
auto &typeIdColumn = table.addColumn("typeId");
auto &majorVersionColumn = table.addColumn("majorVersion");
auto &minorVersionColumn = table.addColumn("minorVersion");
- table.addUniqueIndex({moduleIdColumn, nameColumn, kindColumn},
+ table.addUniqueIndex({moduleIdColumn, nameColumn},
"majorVersion IS NULL AND minorVersion IS NULL");
- table.addUniqueIndex({moduleIdColumn, nameColumn, kindColumn, majorVersionColumn},
+ table.addUniqueIndex({moduleIdColumn, nameColumn, majorVersionColumn},
"majorVersion IS NOT NULL AND minorVersion IS NULL");
- table.addUniqueIndex(
- {moduleIdColumn, nameColumn, kindColumn, majorVersionColumn, minorVersionColumn},
- "majorVersion IS NOT NULL AND minorVersion IS NOT NULL");
+ table.addUniqueIndex({moduleIdColumn, nameColumn, majorVersionColumn, minorVersionColumn},
+ "majorVersion IS NOT NULL AND minorVersion IS NOT NULL");
- table.addIndex({typeIdColumn}, "kind=1");
+ table.addIndex({typeIdColumn});
table.initialize(database);
}
@@ -1823,6 +1973,7 @@ private:
Sqlite::Enforment::Deferred);
auto &majorVersionColumn = table.addColumn("majorVersion");
auto &minorVersionColumn = table.addColumn("minorVersion");
+ table.addColumn("kind");
table.addUniqueIndex({sourceIdColumn, moduleIdColumn},
"majorVersion IS NULL AND minorVersion IS NULL");
@@ -1856,18 +2007,18 @@ private:
public:
Database &database;
Initializer initializer;
+ ModuleCache moduleCache{ModuleStorageAdapter{*this}};
ReadWriteStatement<1> upsertTypeStatement{
- "INSERT INTO types(moduleId, name, accessSemantics, sourceId) VALUES(?1, ?2, "
- "?3, nullif(?4, -1)) ON CONFLICT DO UPDATE SET accessSemantics=excluded.accessSemantics, "
- "sourceId=excluded.sourceId WHERE accessSemantics IS NOT excluded.accessSemantics OR "
- "sourceId IS NOT excluded.sourceId RETURNING typeId",
+ "INSERT INTO types(sourceId, name, accessSemantics) VALUES(?1, ?2, ?3) ON CONFLICT DO "
+ "UPDATE SET accessSemantics=excluded.accessSemantics WHERE accessSemantics IS NOT "
+ "excluded.accessSemantics RETURNING typeId",
database};
WriteStatement updatePrototypeStatement{
"UPDATE types SET prototypeId=?2, prototypeNameId=?3 WHERE typeId=?1 AND (prototypeId IS "
"NOT ?2 OR prototypeNameId IS NOT ?3)",
database};
mutable ReadStatement<1> selectTypeIdByExportedNameStatement{
- "SELECT typeId FROM exportedTypeNames WHERE name=?1 AND kind=1", database};
+ "SELECT typeId FROM exportedTypeNames WHERE name=?1", database};
mutable ReadStatement<1> selectPrototypeIdStatement{
"WITH RECURSIVE "
" typeSelection(typeId) AS ("
@@ -1925,18 +2076,14 @@ public:
"INSERT INTO sources(sourceContextId, sourceName) VALUES (?,?)", database};
mutable ReadStatement<3> selectAllSourcesStatement{
"SELECT sourceName, sourceContextId, sourceId FROM sources", database};
- mutable ReadStatement<5> selectTypeByTypeIdStatement{
- "SELECT moduleId, name, (SELECT name FROM types WHERE typeId=outerTypes.prototypeId), "
- "accessSemantics, ifnull(sourceId, -1) FROM types AS outerTypes WHERE typeId=?",
+ mutable ReadStatement<4> selectTypeByTypeIdStatement{
+ "SELECT sourceId, name, prototypeId, accessSemantics FROM types WHERE typeId=?", database};
+ mutable ReadStatement<4> selectExportedTypesByTypeIdStatement{
+ "SELECT moduleId, name, ifnull(majorVersion, -1), ifnull(minorVersion, -1) FROM "
+ "exportedTypeNames WHERE typeId=?",
database};
- mutable ReadStatement<3> selectExportedTypesByTypeIdStatement{
- "SELECT name, ifnull(majorVersion, -1), ifnull(minorVersion, -1) FROM exportedTypeNames "
- "WHERE typeId=? AND kind=1",
- database};
- mutable ReadStatement<6> selectTypesStatement{
- "SELECT moduleId, name, typeId, (SELECT name FROM types WHERE "
- "typeId=t.prototypeId), accessSemantics, ifnull(sourceId, -1) FROM types AS "
- "t",
+ mutable ReadStatement<5> selectTypesStatement{
+ "SELECT sourceId, name, typeId, ifnull(prototypeId, -1), accessSemantics FROM types",
database};
ReadStatement<1> selectNotUpdatedTypesInSourcesStatement{
"SELECT typeId FROM types WHERE (sourceId IN carray(?1) AND typeId NOT IN carray(?2))",
@@ -1953,10 +2100,9 @@ public:
"DELETE FROM signalDeclarations WHERE typeId=?", database};
WriteStatement deleteTypeStatement{"DELETE FROM types WHERE typeId=?", database};
mutable ReadStatement<4> selectPropertyDeclarationsByTypeIdStatement{
- "SELECT name, (SELECT name FROM types WHERE typeId=pd.propertyTypeId), propertyTraits, "
- "(SELECT name FROM propertyDeclarations WHERE "
- "propertyDeclarationId=pd.aliasPropertyDeclarationId) FROM propertyDeclarations AS pd "
- "WHERE typeId=?",
+ "SELECT name, nullif(propertyTypeId, -1), propertyTraits, (SELECT name FROM "
+ "propertyDeclarations WHERE propertyDeclarationId=pd.aliasPropertyDeclarationId) FROM "
+ "propertyDeclarations AS pd WHERE typeId=?",
database};
ReadStatement<6> selectPropertyDeclarationsForTypeIdStatement{
"SELECT name, propertyTraits, propertyTypeId, propertyImportedTypeNameId, "
@@ -2081,25 +2227,18 @@ public:
database};
WriteStatement deleteEnumerationDeclarationStatement{
"DELETE FROM enumerationDeclarations WHERE enumerationDeclarationId=?", database};
- WriteStatement insertModuleStatement{"INSERT INTO modules(name, moduleId) VALUES(?1, ?2)",
- database};
- WriteStatement updateModuleStatement{"UPDATE modules SET name=?2 WHERE moduleId=?1", database};
- WriteStatement deleteModuleStatement{"DELETE FROM modules WHERE moduleId=?", database};
mutable ReadStatement<1> selectModuleIdByNameStatement{
"SELECT moduleId FROM modules WHERE name=? LIMIT 1", database};
- mutable ReadStatement<2> selectModulesForIdsStatement{
- "SELECT name, moduleId FROM modules WHERE moduleId IN carray(?1) ORDER BY "
- "moduleId",
- database};
- mutable ReadStatement<2> selectAllModulesStatement{
- "SELECT name, moduleId FROM modules ORDER BY moduleId", database};
- mutable ReadStatement<1> selectTypeIdsForModuleIdStatement{
- "SELECT typeId FROM types WHERE moduleId=?", database};
- mutable ReadStatement<1> selectTypeIdByModuleIdAndNameStatement{
- "SELECT typeId FROM types WHERE moduleId=?1 and name=?2", database};
+ mutable ReadWriteStatement<1> insertModuleNameStatement{
+ "INSERT INTO modules(name) VALUES(?1) RETURNING moduleId", database};
+ mutable ReadStatement<1> selectModuleNameStatement{
+ "SELECT name FROM modules WHERE moduleId =?1", database};
+ mutable ReadStatement<2> selectAllModulesStatement{"SELECT name, moduleId FROM modules", database};
+ mutable ReadStatement<1> selectTypeIdBySourceIdAndNameStatement{
+ "SELECT typeId FROM types WHERE sourceId=?1 and name=?2", database};
mutable ReadStatement<1> selectTypeIdByModuleIdsAndExportedNameStatement{
"SELECT typeId FROM exportedTypeNames WHERE moduleId IN carray(?1, ?2, 'int32') AND "
- "name=?3 AND kind=1",
+ "name=?3",
database};
mutable ReadStatement<5> selectDocumentImportForSourceIdStatement{
"SELECT importId, sourceId, moduleId, ifnull(majorVersion, -1), ifnull(minorVersion, -1) "
@@ -2241,8 +2380,8 @@ public:
WriteStatement deleteFileStatusStatement{"DELETE FROM fileStatuses WHERE sourceId=?1", database};
WriteStatement updateFileStatusStatement{
"UPDATE fileStatuses SET size=?2, lastModified=?3 WHERE sourceId=?1", database};
- ReadStatement<2> selectModuleAndTypeIdBySourceIdStatement{
- "SELECT moduleId, typeId FROM types WHERE sourceId=?", database};
+ ReadStatement<1> selectTypeIdBySourceIdStatement{"SELECT typeId FROM types WHERE sourceId=?",
+ database};
mutable ReadStatement<1> selectImportedTypeNameIdStatement{
"SELECT importedTypeNameId FROM importedTypeNames WHERE kind=?1 AND importOrSourceId=?2 "
"AND name=?3 LIMIT 1",
@@ -2251,24 +2390,24 @@ public:
"INSERT INTO importedTypeNames(kind, importOrSourceId, name) VALUES (?1, ?2, ?3) "
"RETURNING importedTypeNameId",
database};
- mutable ReadStatement<1> selectImportIdBySourceIdAndImportNameStatement{
- "SELECT importId FROM documentImports JOIN modules AS m USING(moduleId) WHERE sourceId=?1 "
- "AND m.name=?2 AND majorVersion IS NULL AND minorVersion IS NULL LIMIT 1",
+ mutable ReadStatement<1> selectImportIdBySourceIdAndModuleIdStatement{
+ "SELECT importId FROM documentImports WHERE sourceId=?1 AND moduleId=?2 AND majorVersion "
+ "IS NULL AND minorVersion IS NULL LIMIT 1",
database};
- mutable ReadStatement<1> selectImportIdBySourceIdAndImportNameAndMajorVersionStatement{
- "SELECT importId FROM documentImports JOIN modules AS m USING(moduleId) WHERE sourceId=?1 "
- "AND m.name=?2 AND majorVersion=?3 AND minorVersion IS NULL LIMIT 1",
+ mutable ReadStatement<1> selectImportIdBySourceIdAndModuleIdAndMajorVersionStatement{
+ "SELECT importId FROM documentImports WHERE sourceId=?1 AND moduleId=?2 AND "
+ "majorVersion=?3 AND minorVersion IS NULL LIMIT 1",
database};
- mutable ReadStatement<1> selectImportIdBySourceIdAndImportNameAndVersionStatement{
- "SELECT importId FROM documentImports JOIN modules AS m USING(moduleId) WHERE sourceId=?1 "
- "AND m.name=?2 AND majorVersion=?3 AND minorVersion=?4 LIMIT 1",
+ mutable ReadStatement<1> selectImportIdBySourceIdAndModuleIdAndVersionStatement{
+ "SELECT importId FROM documentImports WHERE sourceId=?1 AND moduleId=?2 AND "
+ "majorVersion=?3 AND minorVersion=?4 LIMIT 1",
database};
mutable ReadStatement<1> selectKindFromImportedTypeNamesStatement{
"SELECT kind FROM importedTypeNames WHERE importedTypeNameId=?1", database};
mutable ReadStatement<1> selectTypeIdForQualifiedImportedTypeNameNamesStatement{
"SELECT typeId FROM importedTypeNames AS itn JOIN documentImports AS di ON "
"importOrSourceId=importId JOIN exportedTypeNames AS etn USING(moduleId) WHERE "
- "itn.kind=2 AND importedTypeNameId=?1 AND itn.name=etn.name AND etn.kind=1 AND "
+ "itn.kind=2 AND importedTypeNameId=?1 AND itn.name=etn.name AND "
"(di.majorVersion IS NULL OR (di.majorVersion=etn.majorVersion AND (di.minorVersion IS "
"NULL OR di.minorVersion>=etn.minorVersion))) ORDER BY etn.majorVersion DESC NULLS FIRST, "
"etn.minorVersion DESC NULLS FIRST LIMIT 1",
@@ -2276,39 +2415,29 @@ public:
mutable ReadStatement<1> selectTypeIdForImportedTypeNameNamesStatement{
"SELECT typeId FROM importedTypeNames AS itn JOIN documentImports AS di ON "
"importOrSourceId=sourceId JOIN exportedTypeNames AS etn USING(moduleId) WHERE "
- "itn.kind=1 AND importedTypeNameId=?1 AND itn.name=etn.name AND etn.kind=1 AND "
+ "itn.kind=1 AND importedTypeNameId=?1 AND itn.name=etn.name AND "
"(di.majorVersion IS NULL OR (di.majorVersion=etn.majorVersion AND (di.minorVersion IS "
"NULL OR di.minorVersion>=etn.minorVersion))) ORDER BY etn.majorVersion DESC NULLS FIRST, "
"etn.minorVersion DESC NULLS FIRST LIMIT 1",
database};
- mutable ReadStatement<1> selectTypeIdForNativeTypeNameNamesStatement{
- "SELECT typeId FROM importedTypeNames AS itn JOIN documentImports AS di ON "
- "importOrSourceId=sourceId JOIN exportedTypeNames AS etn USING(moduleId) WHERE itn.kind=0 "
- "AND importedTypeNameId=?1 AND itn.name=etn.name AND etn.kind=0 LIMIT 1",
- database};
WriteStatement deleteAllSourcesStatement{"DELETE FROM sources", database};
WriteStatement deleteAllSourceContextsStatement{"DELETE FROM sourceContexts", database};
- mutable ReadStatement<6> selectExportedTypesForTypeIdStatement{
- "SELECT moduleId, name, ifnull(majorVersion, -1), ifnull(minorVersion, -1), typeId, "
- "exportedTypeNameId FROM exportedTypeNames WHERE typeId IN carray(?1, ?2, 'int64') AND "
- "kind=1 ORDER BY moduleId, name, majorVersion, minorVersion",
- database};
- WriteStatement upsertExportedTypeNamesWithVersionStatement{
- "INSERT INTO exportedTypeNames(moduleId, name, kind, majorVersion, minorVersion, typeId) "
- "VALUES(?1, ?2, ?3, ?4, ?5, ?6) ON CONFLICT DO UPDATE SET typeId=excluded.typeId",
- database};
- WriteStatement upsertExportedTypeNamesWithMajorVersionStatement{
- "INSERT INTO exportedTypeNames(moduleId, name, kind, majorVersion, typeId) "
- "VALUES(?1, ?2, ?3, ?4, ?5) ON CONFLICT DO UPDATE SET typeId=excluded.typeId",
- database};
- WriteStatement upsertExportedTypeNamesWithoutVersionStatement{
- "INSERT INTO exportedTypeNames(moduleId, name, kind, typeId) VALUES(?1, ?2, ?3, ?4) ON "
- "CONFLICT DO UPDATE SET typeId=excluded.typeId",
- database};
- WriteStatement upsertExportedTypeNameStatement{
- "INSERT INTO exportedTypeNames(moduleId, name, kind, typeId) VALUES(?1, ?2, ?3, ?4) ON "
- "CONFLICT DO UPDATE SET typeId=excluded.typeId WHERE typeId IS NOT excluded.typeId",
- database};
+ mutable ReadStatement<6> selectExportedTypesForSourceIdsStatement{
+ "SELECT moduleId, etn.name, ifnull(majorVersion, -1), ifnull(minorVersion, -1), typeId, "
+ "exportedTypeNameId FROM exportedTypeNames AS etn JOIN types USING(typeId) WHERE sourceId "
+ "IN carray(?1) OR typeId in carray(?2) ORDER BY moduleId, etn.name, majorVersion, "
+ "minorVersion",
+ database};
+ WriteStatement insertExportedTypeNamesWithVersionStatement{
+ "INSERT INTO exportedTypeNames(moduleId, name, majorVersion, minorVersion, typeId) "
+ "VALUES(?1, ?2, ?3, ?4, ?5)",
+ database};
+ WriteStatement insertExportedTypeNamesWithMajorVersionStatement{
+ "INSERT INTO exportedTypeNames(moduleId, name, majorVersion, typeId) "
+ "VALUES(?1, ?2, ?3, ?4)",
+ database};
+ WriteStatement insertExportedTypeNamesWithoutVersionStatement{
+ "INSERT INTO exportedTypeNames(moduleId, name, typeId) VALUES(?1, ?2, ?3)", database};
WriteStatement deleteExportedTypeNameStatement{
"DELETE FROM exportedTypeNames WHERE exportedTypeNameId=?", database};
WriteStatement updateExportedTypeNameTypeIdStatement{
diff --git a/src/plugins/qmldesigner/designercore/projectstorage/projectstorageexceptions.h b/src/plugins/qmldesigner/designercore/projectstorage/projectstorageexceptions.h
index 0d23e11605..42790bded6 100644
--- a/src/plugins/qmldesigner/designercore/projectstorage/projectstorageexceptions.h
+++ b/src/plugins/qmldesigner/designercore/projectstorage/projectstorageexceptions.h
@@ -101,4 +101,10 @@ public:
const char *what() const noexcept override { return "There is a prototype chain cycle!"; }
};
+class CannotParseQmlTypesFile : std::exception
+{
+public:
+ const char *what() const noexcept override { return "Cannot parse qml types file!"; }
+};
+
} // namespace QmlDesigner
diff --git a/src/plugins/qmldesigner/designercore/projectstorage/projectstorageinterface.h b/src/plugins/qmldesigner/designercore/projectstorage/projectstorageinterface.h
index 302a1801a2..7d27bd22f1 100644
--- a/src/plugins/qmldesigner/designercore/projectstorage/projectstorageinterface.h
+++ b/src/plugins/qmldesigner/designercore/projectstorage/projectstorageinterface.h
@@ -33,15 +33,12 @@ namespace QmlDesigner {
class ProjectStorageInterface
{
public:
- virtual void synchronize(Storage::Modules modules,
- Storage::Imports imports,
- Storage::Types types,
- SourceIds sourceIds,
- FileStatuses fileStatuses)
- = 0;
+ virtual void synchronize(Storage::SynchronizationPackage package) = 0;
+
+ virtual ModuleId moduleId(Utils::SmallStringView name) = 0;
virtual FileStatus fetchFileStatus(SourceId sourceId) const = 0;
- virtual SourceIds fetchSourceDependencieIds(SourceId sourceId) const = 0;
+ virtual Storage::ProjectDatas fetchProjectDatas(SourceId sourceId) const = 0;
protected:
~ProjectStorageInterface() = default;
diff --git a/src/plugins/qmldesigner/designercore/projectstorage/projectstoragetypes.h b/src/plugins/qmldesigner/designercore/projectstorage/projectstoragetypes.h
index 50db7c4853..ef05539076 100644
--- a/src/plugins/qmldesigner/designercore/projectstorage/projectstoragetypes.h
+++ b/src/plugins/qmldesigner/designercore/projectstorage/projectstoragetypes.h
@@ -25,6 +25,7 @@
#pragma once
+#include "filestatus.h"
#include "projectstorageids.h"
#include <utils/smallstring.h>
@@ -35,10 +36,10 @@
namespace QmlDesigner::Storage {
-enum class TypeAccessSemantics : int { Invalid, Reference, Value, Sequence, IsEnum = 1 << 8 };
+enum class TypeAccessSemantics : int { None, Reference, Value, Sequence, IsEnum = 1 << 8 };
enum class PropertyDeclarationTraits : unsigned int {
- Non = 0,
+ None = 0,
IsReadOnly = 1 << 0,
IsPointer = 1 << 1,
IsList = 1 << 2
@@ -121,38 +122,6 @@ public:
VersionNumber minor;
};
-class Module
-{
-public:
- explicit Module() = default;
-
- explicit Module(Utils::SmallStringView name, SourceId sourceId = SourceId{})
- : name{name}
- , sourceId{sourceId}
- {}
-
- explicit Module(QStringView name, SourceId sourceId = SourceId{})
- : name{name}
- , sourceId{sourceId}
- {}
-
- explicit Module(Utils::SmallStringView name, int sourceId)
- : name{name}
- , sourceId{sourceId}
- {}
-
- friend bool operator==(const Module &first, const Module &second)
- {
- return first.name == second.name;
- }
-
-public:
- Utils::PathString name;
- SourceId sourceId;
-};
-
-using Modules = std::vector<Module>;
-
enum class IsQualified : int { No, Yes };
inline int operator-(IsQualified first, IsQualified second)
@@ -165,34 +134,36 @@ inline int operator<(IsQualified first, IsQualified second)
return static_cast<int>(first) < static_cast<int>(second);
}
+enum class ImportKind : char { Module, Directory, QmlTypesDependency };
+
class Import
{
public:
explicit Import() = default;
- explicit Import(Utils::SmallStringView name, Version version, SourceId sourceId)
- : name{name}
- , version{version}
+ explicit Import(ModuleId moduleId, Version version, SourceId sourceId)
+ : version{version}
+ , moduleId{moduleId}
, sourceId{sourceId}
{}
- explicit Import(Utils::SmallStringView name, int majorVersion, int minorVersion, int sourceId)
- : name{name}
+ explicit Import(int moduleId, int majorVersion, int minorVersion, int sourceId)
+ : moduleId{moduleId}
, version{majorVersion, minorVersion}
, sourceId{sourceId}
{}
friend bool operator==(const Import &first, const Import &second)
{
- return first.name == second.name && first.version == second.version
+ return first.moduleId == second.moduleId && first.version == second.version
&& first.sourceId == second.sourceId;
}
public:
- Utils::PathString name;
Version version;
ModuleId moduleId;
SourceId sourceId;
+ Utils::SmallString aliasName;
};
using Imports = std::vector<Import>;
@@ -269,6 +240,12 @@ public:
, version{version}
{}
+ explicit ExportedType(ModuleId moduleId, Utils::SmallStringView name, Version version = Version{})
+ : name{name}
+ , version{version}
+ , moduleId{moduleId}
+ {}
+
explicit ExportedType(Utils::SmallStringView name, Version version, TypeId typeId, ModuleId moduleId)
: name{name}
, version{version}
@@ -276,9 +253,10 @@ public:
, moduleId{moduleId}
{}
- explicit ExportedType(Utils::SmallStringView name, int majorVersion, int minorVersion)
+ explicit ExportedType(int moduleId, Utils::SmallStringView name, int majorVersion, int minorVersion)
: name{name}
, version{majorVersion, minorVersion}
+ , moduleId{moduleId}
{}
friend bool operator==(const ExportedType &first, const ExportedType &second)
@@ -299,6 +277,11 @@ class ExportedTypeView
{
public:
explicit ExportedTypeView() = default;
+ explicit ExportedTypeView(ModuleId moduleId, Utils::SmallStringView name, Storage::Version version)
+ : name{name}
+ , version{version}
+ , moduleId{moduleId}
+ {}
explicit ExportedTypeView(int moduleId,
Utils::SmallStringView name,
int majorVersion,
@@ -552,6 +535,15 @@ public:
{}
explicit PropertyDeclaration(Utils::SmallStringView name,
+ TypeId propertyTypeId,
+ PropertyDeclarationTraits traits)
+ : name{name}
+ , traits{traits}
+ , propertyTypeId{propertyTypeId}
+ , kind{PropertyKind::Property}
+ {}
+
+ explicit PropertyDeclaration(Utils::SmallStringView name,
ImportedTypeName typeName,
PropertyDeclarationTraits traits,
Utils::SmallStringView aliasPropertyName)
@@ -563,13 +555,24 @@ public:
{}
explicit PropertyDeclaration(Utils::SmallStringView name,
- Utils::SmallStringView typeName,
+ TypeId propetyTypeId,
+ PropertyDeclarationTraits traits,
+ Utils::SmallStringView aliasPropertyName)
+ : name{name}
+ , aliasPropertyName{aliasPropertyName}
+ , traits{traits}
+ , propertyTypeId{propertyTypeId}
+ , kind{PropertyKind::Property}
+ {}
+
+ explicit PropertyDeclaration(Utils::SmallStringView name,
+ long long propertyTypeId,
int traits,
Utils::SmallStringView aliasPropertyName)
: name{name}
- , typeName{NativeType{typeName}}
, aliasPropertyName{aliasPropertyName}
, traits{static_cast<PropertyDeclarationTraits>(traits)}
+ , propertyTypeId{propertyTypeId}
, kind{PropertyKind::Property}
{}
@@ -594,6 +597,7 @@ public:
ImportedTypeName typeName;
Utils::SmallString aliasPropertyName;
PropertyDeclarationTraits traits = {};
+ TypeId propertyTypeId;
TypeId typeId;
PropertyKind kind = PropertyKind::Property;
};
@@ -632,8 +636,7 @@ class Type
{
public:
explicit Type() = default;
- explicit Type(ModuleId moduleId,
- Utils::SmallStringView typeName,
+ explicit Type(Utils::SmallStringView typeName,
ImportedTypeName prototype,
TypeAccessSemantics accessSemantics,
SourceId sourceId,
@@ -650,37 +653,42 @@ public:
, functionDeclarations{std::move(functionDeclarations)}
, signalDeclarations{std::move(signalDeclarations)}
, enumerationDeclarations{std::move(enumerationDeclarations)}
- , moduleId{moduleId}
, accessSemantics{accessSemantics}
, sourceId{sourceId}
, changeLevel{changeLevel}
{}
- explicit Type(ModuleId moduleId,
- Utils::SmallStringView typeName,
+ explicit Type(Utils::SmallStringView typeName,
+ TypeId prototypeId,
+ TypeAccessSemantics accessSemantics,
+ SourceId sourceId)
+ : typeName{typeName}
+ , accessSemantics{accessSemantics}
+ , sourceId{sourceId}
+ , prototypeId{prototypeId}
+ {}
+
+ explicit Type(Utils::SmallStringView typeName,
Utils::SmallStringView prototype,
int accessSemantics,
int sourceId)
: typeName{typeName}
, prototype{NativeType{prototype}}
- , moduleId{moduleId}
, accessSemantics{static_cast<TypeAccessSemantics>(accessSemantics)}
, sourceId{sourceId}
{}
- explicit Type(int moduleId,
+ explicit Type(int sourceId,
Utils::SmallStringView typeName,
long long typeId,
- Utils::SmallStringView prototype,
- int accessSemantics,
- int sourceId)
+ long long prototypeId,
+ int accessSemantics)
: typeName{typeName}
- , prototype{NativeType{prototype}}
- , moduleId{moduleId}
, accessSemantics{static_cast<TypeAccessSemantics>(accessSemantics)}
, sourceId{sourceId}
, typeId{typeId}
+ , prototypeId{prototypeId}
{}
friend bool operator==(const Type &first, const Type &second) noexcept
@@ -690,7 +698,6 @@ public:
&& first.propertyDeclarations == second.propertyDeclarations
&& first.functionDeclarations == second.functionDeclarations
&& first.signalDeclarations == second.signalDeclarations
- && first.moduleId == second.moduleId && first.sourceId == second.sourceId
&& first.sourceId == second.sourceId;
}
@@ -702,31 +709,52 @@ public:
FunctionDeclarations functionDeclarations;
SignalDeclarations signalDeclarations;
EnumerationDeclarations enumerationDeclarations;
- TypeAccessSemantics accessSemantics = TypeAccessSemantics::Invalid;
+ TypeAccessSemantics accessSemantics = TypeAccessSemantics::None;
SourceId sourceId;
TypeId typeId;
- ModuleId moduleId;
+ TypeId prototypeId;
ChangeLevel changeLevel = ChangeLevel::Full;
};
using Types = std::vector<Type>;
-class ModuleView
+class ProjectData
{
public:
- explicit ModuleView(Utils::SmallStringView name, int sourceId)
- : name{name}
- , sourceId{sourceId}
+ ModuleId extraModuleId;
+ SourceId sourceId;
+};
+
+using ProjectDatas = std::vector<ProjectData>;
+
+class SynchronizationPackage
+{
+public:
+ SynchronizationPackage() = default;
+ SynchronizationPackage(Imports imports, Types types, SourceIds sourceIds)
+ : imports{std::move(imports)}
+ , types{std::move(types)}
+ , sourceIds(std::move(sourceIds))
{}
- friend bool operator==(const ModuleView &first, const ModuleView &second)
- {
- return first.name == second.name && first.sourceId == second.sourceId;
- }
+ SynchronizationPackage(Types types)
+ : types{std::move(types)}
+ {}
+
+ SynchronizationPackage(SourceIds sourceIds)
+ : sourceIds(std::move(sourceIds))
+ {}
+
+ SynchronizationPackage(SourceIds sourceIds, FileStatuses fileStatuses)
+ : sourceIds(std::move(sourceIds))
+ , fileStatuses(std::move(fileStatuses))
+ {}
public:
- Utils::SmallStringView name;
- SourceId sourceId;
+ Imports imports;
+ Types types;
+ SourceIds sourceIds;
+ FileStatuses fileStatuses;
};
} // namespace QmlDesigner::Storage
diff --git a/src/plugins/qmldesigner/designercore/projectstorage/projectstorageupdater.cpp b/src/plugins/qmldesigner/designercore/projectstorage/projectstorageupdater.cpp
index b5a7945181..cc91a06fae 100644
--- a/src/plugins/qmldesigner/designercore/projectstorage/projectstorageupdater.cpp
+++ b/src/plugins/qmldesigner/designercore/projectstorage/projectstorageupdater.cpp
@@ -52,40 +52,34 @@ ComponentReferences createComponentReferences(const QMultiHash<QString, QmlDirPa
void ProjectUpdater::update()
{
- Storage::Modules modules;
- Storage::Imports imports;
- Storage::Types types;
- SourceIds sourceIds;
- FileStatuses fileStatuses;
+ Storage::SynchronizationPackage package;
for (const QString &qmldirPath : m_projectManager.qtQmlDirs()) {
SourcePath qmldirSourcePath{qmldirPath};
SourceId qmlDirSourceId = m_pathCache.sourceId(qmldirSourcePath);
- switch (fileState(qmlDirSourceId, fileStatuses)) {
+ switch (fileState(qmlDirSourceId, package.fileStatuses)) {
case FileState::Changed: {
QmlDirParser parser;
parser.parse(m_fileSystem.contentAsQString(qmldirPath));
- modules.emplace_back(parser.typeNamespace(), qmlDirSourceId);
-
- sourceIds.push_back(qmlDirSourceId);
+ package.sourceIds.push_back(qmlDirSourceId);
SourceContextId directoryId = m_pathCache.sourceContextId(qmlDirSourceId);
- parseTypeInfos(parser.typeInfos(), directoryId, imports, types, sourceIds, fileStatuses);
+ Utils::PathString moduleName{parser.typeNamespace()};
+ ModuleId moduleId = m_projectStorage.moduleId(moduleName);
+
+ parseTypeInfos(parser.typeInfos(), directoryId, package);
parseQmlComponents(createComponentReferences(parser.components()),
directoryId,
- ModuleId{&qmlDirSourceId},
- imports,
- types,
- sourceIds,
- fileStatuses);
+ moduleId,
+ package);
break;
}
case FileState::NotChanged: {
- SourceIds qmltypesSourceIds = m_projectStorage.fetchSourceDependencieIds(qmlDirSourceId);
- parseTypeInfos(qmltypesSourceIds, imports, types, sourceIds, fileStatuses);
+ auto qmlProjectDatas = m_projectStorage.fetchProjectDatas(qmlDirSourceId);
+ parseTypeInfos(qmlProjectDatas, package);
break;
}
case FileState::NotExists: {
@@ -95,21 +89,14 @@ void ProjectUpdater::update()
}
}
- m_projectStorage.synchronize(std::move(modules),
- std::move(imports),
- std::move(types),
- std::move(sourceIds),
- std::move(fileStatuses));
+ m_projectStorage.synchronize(std::move(package));
}
void ProjectUpdater::pathsWithIdsChanged(const std::vector<IdPaths> &idPaths) {}
void ProjectUpdater::parseTypeInfos(const QStringList &typeInfos,
SourceContextId directoryId,
- Storage::Imports &imports,
- Storage::Types &types,
- SourceIds &sourceIds,
- FileStatuses &fileStatuses)
+ Storage::SynchronizationPackage &package)
{
QString directory{m_pathCache.sourceContextPath(directoryId)};
@@ -117,44 +104,37 @@ void ProjectUpdater::parseTypeInfos(const QStringList &typeInfos,
SourceId sourceId = m_pathCache.sourceId(directoryId, Utils::SmallString{typeInfo});
QString qmltypesPath = directory + "/" + typeInfo;
- parseTypeInfo(sourceId, qmltypesPath, imports, types, sourceIds, fileStatuses);
+ Storage::ProjectData projectData{ModuleId{}, sourceId};
+
+ parseTypeInfo(projectData, qmltypesPath, package);
}
}
-void ProjectUpdater::parseTypeInfos(const SourceIds &qmltypesSourceIds,
- Storage::Imports &imports,
- Storage::Types &types,
- SourceIds &sourceIds,
- FileStatuses &fileStatuses)
+void ProjectUpdater::parseTypeInfos(const Storage::ProjectDatas &projectDatas,
+ Storage::SynchronizationPackage &package)
{
- for (SourceId sourceId : qmltypesSourceIds) {
- QString qmltypesPath = m_pathCache.sourcePath(sourceId).toQString();
+ for (const Storage::ProjectData &projectData : projectDatas) {
+ QString qmltypesPath = m_pathCache.sourcePath(projectData.sourceId).toQString();
- parseTypeInfo(sourceId, qmltypesPath, imports, types, sourceIds, fileStatuses);
+ parseTypeInfo(projectData, qmltypesPath, package);
}
}
-void ProjectUpdater::parseTypeInfo(SourceId sourceId,
+void ProjectUpdater::parseTypeInfo(const Storage::ProjectData &projectData,
const QString &qmltypesPath,
- Storage::Imports &imports,
- Storage::Types &types,
- SourceIds &sourceIds,
- FileStatuses &fileStatuses)
+ Storage::SynchronizationPackage &package)
{
- if (fileState(sourceId, fileStatuses) == FileState::Changed) {
- sourceIds.push_back(sourceId);
+ if (fileState(projectData.sourceId, package.fileStatuses) == FileState::Changed) {
+ package.sourceIds.push_back(projectData.sourceId);
const auto content = m_fileSystem.contentAsQString(qmltypesPath);
- m_qmlTypesParser.parse(content, imports, types, sourceIds);
+ m_qmlTypesParser.parse(content, package.imports, package.types, projectData);
}
}
void ProjectUpdater::parseQmlComponents(ComponentReferences components,
SourceContextId directoryId,
ModuleId moduleId,
- Storage::Imports &imports,
- Storage::Types &types,
- SourceIds &sourceIds,
- FileStatuses &fileStatuses)
+ Storage::SynchronizationPackage &package)
{
std::sort(components.begin(), components.end(), [](auto &&first, auto &&second) {
return std::tie(first.get().typeName, first.get().majorVersion, first.get().minorVersion)
@@ -174,23 +154,23 @@ void ProjectUpdater::parseQmlComponents(ComponentReferences components,
Utils::SmallString fileName{component.fileName};
SourceId sourceId = m_pathCache.sourceId(directoryId, fileName);
- if (fileState(sourceId, fileStatuses) != FileState::Changed)
+ if (fileState(sourceId, package.fileStatuses) != FileState::Changed)
continue;
- sourceIds.push_back(sourceId);
+ package.sourceIds.push_back(sourceId);
const auto content = m_fileSystem.contentAsQString(directory + "/" + component.fileName);
- auto type = m_qmlDocumentParser.parse(content, imports);
+ auto type = m_qmlDocumentParser.parse(content, package.imports);
type.typeName = fileName;
- type.moduleId = moduleId;
type.accessSemantics = Storage::TypeAccessSemantics::Reference;
type.sourceId = sourceId;
type.exportedTypes.push_back(
- Storage::ExportedType{Utils::SmallString{component.typeName},
+ Storage::ExportedType{moduleId,
+ Utils::SmallString{component.typeName},
Storage::Version{component.majorVersion, component.minorVersion}});
- types.push_back(std::move(type));
+ package.types.push_back(std::move(type));
}
}
diff --git a/src/plugins/qmldesigner/designercore/projectstorage/projectstorageupdater.h b/src/plugins/qmldesigner/designercore/projectstorage/projectstorageupdater.h
index dfe8ce05c4..e3323d7609 100644
--- a/src/plugins/qmldesigner/designercore/projectstorage/projectstorageupdater.h
+++ b/src/plugins/qmldesigner/designercore/projectstorage/projectstorageupdater.h
@@ -88,28 +88,16 @@ private:
void parseTypeInfos(const QStringList &typeInfos,
SourceContextId directoryId,
- Storage::Imports &imports,
- Storage::Types &types,
- SourceIds &sourceIds,
- FileStatuses &fileStatuses);
- void parseTypeInfos(const SourceIds &qmltypesSourceIds,
- Storage::Imports &imports,
- Storage::Types &types,
- SourceIds &sourceIds,
- FileStatuses &fileStatuses);
- void parseTypeInfo(SourceId sourceId,
+ Storage::SynchronizationPackage &package);
+ void parseTypeInfos(const Storage::ProjectDatas &projectDatas,
+ Storage::SynchronizationPackage &package);
+ void parseTypeInfo(const Storage::ProjectData &projectData,
const QString &qmltypesPath,
- Storage::Imports &imports,
- Storage::Types &types,
- SourceIds &sourceIds,
- FileStatuses &fileStatuses);
+ Storage::SynchronizationPackage &package);
void parseQmlComponents(ComponentReferences components,
SourceContextId directoryId,
ModuleId moduleId,
- Storage::Imports &imports,
- Storage::Types &types,
- SourceIds &sourceIds,
- FileStatuses &fileStatuses);
+ Storage::SynchronizationPackage &package);
FileState fileState(SourceId sourceId, FileStatuses &fileStatuses) const;
diff --git a/src/plugins/qmldesigner/designercore/projectstorage/qmldocumentparser.cpp b/src/plugins/qmldesigner/designercore/projectstorage/qmldocumentparser.cpp
new file mode 100644
index 0000000000..c4a2bae617
--- /dev/null
+++ b/src/plugins/qmldesigner/designercore/projectstorage/qmldocumentparser.cpp
@@ -0,0 +1,197 @@
+/****************************************************************************
+**
+** Copyright (C) 2021 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 "qmldocumentparser.h"
+
+#include "projectstorage.h"
+#include "sourcepathcache.h"
+
+#include <sqlitedatabase.h>
+
+#include <qmldom/qqmldomtop_p.h>
+
+#include <QDateTime>
+
+namespace QmlDesigner {
+
+namespace QmlDom = QQmlJS::Dom;
+
+namespace {
+
+int convertVersionNumber(qint32 versionNumber)
+{
+ return versionNumber < 0 ? -1 : versionNumber;
+}
+
+Storage::Version convertVersion(QmlDom::Version version)
+{
+ return Storage::Version{convertVersionNumber(version.majorVersion),
+ convertVersionNumber(version.minorVersion)};
+}
+
+Utils::PathString convertUri(const QString &uri)
+{
+ Utils::PathString path{QStringView{uri.begin() + 7, uri.end()}};
+ if (path.endsWith("/."))
+ return path;
+ if (path.endsWith("/")) {
+ path += ".";
+ return path;
+ }
+
+ path += "/.";
+ return path;
+}
+
+void addImports(Storage::Imports &imports,
+ const QList<QmlDom::Import> &qmlImports,
+ SourceId sourceId,
+ SourceContextId sourceContextId,
+ QmlDocumentParser::PathCache &pathCache,
+ QmlDocumentParser::ProjectStorage &storage)
+{
+ for (const QmlDom::Import &qmlImport : qmlImports) {
+ if (qmlImport.uri == u"file://.") {
+ auto moduleId = storage.moduleId(pathCache.sourceContextPath(sourceContextId));
+ imports.emplace_back(moduleId, Storage::Version{}, sourceId);
+ } else if (qmlImport.uri.startsWith(u"file://")) {
+ auto moduleId = storage.moduleId(convertUri(qmlImport.uri));
+ imports.emplace_back(moduleId, Storage::Version{}, sourceId);
+ } else {
+ auto moduleId = storage.moduleId(Utils::SmallString{qmlImport.uri});
+ imports.emplace_back(moduleId, convertVersion(qmlImport.version), sourceId);
+ }
+ }
+}
+
+void addPropertyDeclarations(Storage::Type &type, const QmlDom::QmlObject &rootObject)
+{
+ for (const QmlDom::PropertyDefinition &propertyDeclaration : rootObject.propertyDefs()) {
+ type.propertyDeclarations.emplace_back(Utils::SmallString{propertyDeclaration.name},
+ Storage::ImportedType{
+ Utils::SmallString{propertyDeclaration.typeName}},
+ Storage::PropertyDeclarationTraits::None);
+ }
+}
+
+void addParameterDeclaration(Storage::ParameterDeclarations &parameterDeclarations,
+ const QList<QmlDom::MethodParameter> &parameters)
+{
+ for (const QmlDom::MethodParameter &parameter : parameters) {
+ parameterDeclarations.emplace_back(Utils::SmallString{parameter.name},
+ Utils::SmallString{parameter.typeName});
+ }
+}
+
+void addFunctionAndSignalDeclarations(Storage::Type &type, const QmlDom::QmlObject &rootObject)
+{
+ for (const QmlDom::MethodInfo &methodInfo : rootObject.methods()) {
+ if (methodInfo.methodType == QmlDom::MethodInfo::Method) {
+ auto &functionDeclaration = type.functionDeclarations.emplace_back(
+ Utils::SmallString{methodInfo.name}, "", Storage::ParameterDeclarations{});
+ addParameterDeclaration(functionDeclaration.parameters, methodInfo.parameters);
+ } else {
+ auto &signalDeclaration = type.signalDeclarations.emplace_back(
+ Utils::SmallString{methodInfo.name});
+ addParameterDeclaration(signalDeclaration.parameters, methodInfo.parameters);
+ }
+ }
+}
+
+Storage::EnumeratorDeclarations createEnumerators(const QmlDom::EnumDecl &enumeration)
+{
+ Storage::EnumeratorDeclarations enumeratorDeclarations;
+ for (const QmlDom::EnumItem &enumerator : enumeration.values()) {
+ enumeratorDeclarations.emplace_back(Utils::SmallString{enumerator.name()},
+ static_cast<long long>(enumerator.value()));
+ }
+ return enumeratorDeclarations;
+}
+
+void addEnumeraton(Storage::Type &type, const QmlDom::Component &component)
+{
+ for (const QmlDom::EnumDecl &enumeration : component.enumerations()) {
+ Storage::EnumeratorDeclarations enumeratorDeclarations = createEnumerators(enumeration);
+ type.enumerationDeclarations.emplace_back(Utils::SmallString{enumeration.name()},
+ std::move(enumeratorDeclarations));
+ }
+}
+
+} // namespace
+
+Storage::Type QmlDocumentParser::parse(const QString &sourceContent,
+ Storage::Imports &imports,
+ SourceId sourceId,
+ SourceContextId sourceContextId)
+{
+ Storage::Type type;
+
+ QmlDom::DomItem environment = QmlDom::DomEnvironment::create(
+ {},
+ QmlDom::DomEnvironment::Option::SingleThreaded
+ | QmlDom::DomEnvironment::Option::NoDependencies);
+
+ QmlDom::DomItem items;
+
+ environment.loadFile(
+ {},
+ {},
+ sourceContent,
+ QDateTime{},
+ [&](QmlDom::Path, const QmlDom::DomItem &, const QmlDom::DomItem &newItems) {
+ items = newItems;
+ },
+ QmlDom::LoadOption::DefaultLoad,
+ QmlDom::DomType::QmlFile);
+
+ environment.loadPendingDependencies();
+
+ QmlDom::DomItem file = items.field(QmlDom::Fields::currentItem);
+ const QmlDom::QmlFile *qmlFile = file.as<QmlDom::QmlFile>();
+ const auto &components = qmlFile->components();
+
+ if (components.empty())
+ return type;
+
+ const auto &component = components.first();
+ const auto &objects = component.objects();
+
+ if (objects.empty())
+ return type;
+
+ const QmlDom::QmlObject &qmlObject = objects.front();
+
+ type.prototype = Storage::ImportedType{Utils::SmallString{qmlObject.name()}};
+
+ addImports(imports, qmlFile->imports(), sourceId, sourceContextId, m_pathCache, m_storage);
+
+ addPropertyDeclarations(type, qmlObject);
+ addFunctionAndSignalDeclarations(type, qmlObject);
+ addEnumeraton(type, component);
+
+ return type;
+}
+
+} // namespace QmlDesigner
diff --git a/src/plugins/qmldesigner/designercore/projectstorage/qmldocumentparser.h b/src/plugins/qmldesigner/designercore/projectstorage/qmldocumentparser.h
new file mode 100644
index 0000000000..e2dd243405
--- /dev/null
+++ b/src/plugins/qmldesigner/designercore/projectstorage/qmldocumentparser.h
@@ -0,0 +1,63 @@
+/****************************************************************************
+**
+** Copyright (C) 2021 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 "nonlockingmutex.h"
+#include "qmldocumentparserinterface.h"
+
+namespace Sqlite {
+class Database;
+}
+
+namespace QmlDesigner {
+
+template<typename Database>
+class ProjectStorage;
+
+template<typename ProjectStorage, typename Mutex>
+class SourcePathCache;
+
+class QmlDocumentParser
+{
+public:
+ using ProjectStorage = QmlDesigner::ProjectStorage<Sqlite::Database>;
+ using PathCache = QmlDesigner::SourcePathCache<ProjectStorage, NonLockingMutex>;
+
+ QmlDocumentParser(PathCache &pathCache, ProjectStorage &storage)
+ : m_pathCache{pathCache}
+ , m_storage{storage}
+ {}
+
+ virtual Storage::Type parse(const QString &sourceContent,
+ Storage::Imports &imports,
+ SourceId sourceId,
+ SourceContextId sourceContextId);
+
+private:
+ PathCache &m_pathCache;
+ ProjectStorage &m_storage;
+};
+} // namespace QmlDesigner
diff --git a/src/plugins/qmldesigner/designercore/projectstorage/qmltypesparser.cpp b/src/plugins/qmldesigner/designercore/projectstorage/qmltypesparser.cpp
new file mode 100644
index 0000000000..f5d09409aa
--- /dev/null
+++ b/src/plugins/qmldesigner/designercore/projectstorage/qmltypesparser.cpp
@@ -0,0 +1,307 @@
+/****************************************************************************
+**
+** Copyright (C) 2021 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 "qmltypesparser.h"
+
+#include "projectstorage.h"
+#include "sourcepathcache.h"
+
+#include <sqlitedatabase.h>
+
+#include <qmlcompiler/qqmljstypedescriptionreader_p.h>
+#include <qmldom/qqmldomtop_p.h>
+
+#include <QDateTime>
+
+#include <algorithm>
+#include <tuple>
+
+namespace QmlDesigner {
+
+namespace QmlDom = QQmlJS::Dom;
+
+namespace {
+
+void appendImports(Storage::Imports &imports,
+ const QString &dependency,
+ SourceId sourceId,
+ QmlTypesParser::ProjectStorage &storage)
+{
+ auto spaceFound = std::find_if(dependency.begin(), dependency.end(), [](QChar c) {
+ return c.isSpace();
+ });
+
+ Utils::PathString moduleName{QStringView(dependency.begin(), spaceFound)};
+ moduleName.append("-cppnative");
+ ModuleId cppModuleId = storage.moduleId(moduleName);
+
+ auto majorVersionFound = std::find_if(spaceFound, dependency.end(), [](QChar c) {
+ return c.isDigit();
+ });
+ auto majorVersionEnd = std::find_if(majorVersionFound, dependency.end(), [](QChar c) {
+ return !c.isDigit();
+ });
+
+ Storage::Version version;
+
+ QStringView majorVersionString(majorVersionFound, majorVersionEnd);
+ if (!majorVersionString.isEmpty()) {
+ version.major.value = majorVersionString.toInt();
+
+ auto minorVersionFound = std::find_if(majorVersionEnd, dependency.end(), [](QChar c) {
+ return c.isDigit();
+ });
+ auto minorVersionEnd = std::find_if(minorVersionFound, dependency.end(), [](QChar c) {
+ return !c.isDigit();
+ });
+ QStringView minorVersionString(minorVersionFound, minorVersionEnd);
+ if (!minorVersionString.isEmpty())
+ version.minor.value = QStringView(minorVersionFound, minorVersionEnd).toInt();
+ }
+
+ imports.emplace_back(cppModuleId, version, sourceId);
+}
+
+void addImports(Storage::Imports &imports,
+ SourceId sourceId,
+ const QStringList &dependencies,
+ QmlTypesParser::ProjectStorage &storage)
+{
+ for (const QString &dependency : dependencies)
+ appendImports(imports, dependency, sourceId, storage);
+
+ imports.emplace_back(storage.moduleId("QML"), Storage::Version{}, sourceId);
+ imports.emplace_back(storage.moduleId("QtQml-cppnative"), Storage::Version{}, sourceId);
+}
+
+Storage::TypeAccessSemantics createTypeAccessSemantics(QQmlJSScope::AccessSemantics accessSematics)
+{
+ switch (accessSematics) {
+ case QQmlJSScope::AccessSemantics::Reference:
+ return Storage::TypeAccessSemantics::Reference;
+ case QQmlJSScope::AccessSemantics::Value:
+ return Storage::TypeAccessSemantics::Value;
+ case QQmlJSScope::AccessSemantics::None:
+ return Storage::TypeAccessSemantics::None;
+ case QQmlJSScope::AccessSemantics::Sequence:
+ return Storage::TypeAccessSemantics::Sequence;
+ }
+
+ return Storage::TypeAccessSemantics::None;
+}
+
+Storage::Version createVersion(QTypeRevision qmlVersion)
+{
+ return Storage::Version{qmlVersion.majorVersion(), qmlVersion.minorVersion()};
+}
+
+Storage::ExportedTypes createExports(const QList<QQmlJSScope::Export> &qmlExports,
+ const QQmlJSScope &component,
+ QmlTypesParser::ProjectStorage &storage,
+ ModuleId cppModuleId)
+{
+ Storage::ExportedTypes exportedTypes;
+ exportedTypes.reserve(Utils::usize(qmlExports));
+
+ for (const QQmlJSScope::Export &qmlExport : qmlExports) {
+ exportedTypes.emplace_back(storage.moduleId(Utils::SmallString{qmlExport.package()}),
+ Utils::SmallString{qmlExport.type()},
+ createVersion(qmlExport.version()));
+ }
+
+ exportedTypes.emplace_back(cppModuleId, Utils::SmallString{component.internalName()});
+
+ return exportedTypes;
+}
+
+Storage::PropertyDeclarationTraits createPropertyDeclarationTraits(const QQmlJSMetaProperty &qmlProperty)
+{
+ Storage::PropertyDeclarationTraits traits{};
+
+ if (qmlProperty.isList())
+ traits = traits | Storage::PropertyDeclarationTraits::IsList;
+
+ if (qmlProperty.isPointer())
+ traits = traits | Storage::PropertyDeclarationTraits::IsPointer;
+
+ if (!qmlProperty.isWritable())
+ traits = traits | Storage::PropertyDeclarationTraits::IsReadOnly;
+
+ return traits;
+}
+
+Storage::PropertyDeclarations createProperties(const QHash<QString, QQmlJSMetaProperty> &qmlProperties)
+{
+ Storage::PropertyDeclarations propertyDeclarations;
+ propertyDeclarations.reserve(Utils::usize(qmlProperties));
+
+ for (const QQmlJSMetaProperty &qmlProperty : qmlProperties) {
+ propertyDeclarations.emplace_back(Utils::SmallString{qmlProperty.propertyName()},
+ Storage::NativeType{
+ Utils::SmallString{qmlProperty.typeName()}},
+ createPropertyDeclarationTraits(qmlProperty));
+ }
+
+ return propertyDeclarations;
+}
+
+Storage::ParameterDeclarations createParameters(const QQmlJSMetaMethod &qmlMethod)
+{
+ Storage::ParameterDeclarations parameterDeclarations;
+
+ const QStringList &parameterNames = qmlMethod.parameterNames();
+ const QStringList &parameterTypeNames = qmlMethod.parameterTypeNames();
+ auto currentName = parameterNames.begin();
+ auto currentType = parameterTypeNames.begin();
+ auto nameEnd = parameterNames.end();
+ auto typeEnd = parameterTypeNames.end();
+
+ for (; currentName != nameEnd && currentType != typeEnd; ++currentName, ++currentType) {
+ parameterDeclarations.emplace_back(Utils::SmallString{*currentName},
+ Utils::SmallString{*currentType});
+ }
+
+ return parameterDeclarations;
+}
+
+std::tuple<Storage::FunctionDeclarations, Storage::SignalDeclarations> createFunctionAndSignals(
+ const QMultiHash<QString, QQmlJSMetaMethod> &qmlMethods)
+{
+ std::tuple<Storage::FunctionDeclarations, Storage::SignalDeclarations> functionAndSignalDeclarations;
+ Storage::FunctionDeclarations &functionsDeclarations{std::get<0>(functionAndSignalDeclarations)};
+ functionsDeclarations.reserve(Utils::usize(qmlMethods));
+ Storage::SignalDeclarations &signalDeclarations{std::get<1>(functionAndSignalDeclarations)};
+ signalDeclarations.reserve(Utils::usize(qmlMethods));
+
+ for (const QQmlJSMetaMethod &qmlMethod : qmlMethods) {
+ if (qmlMethod.methodType() != QQmlJSMetaMethod::Type::Signal) {
+ functionsDeclarations.emplace_back(Utils::SmallString{qmlMethod.methodName()},
+ Utils::SmallString{qmlMethod.returnTypeName()},
+ createParameters(qmlMethod));
+ } else {
+ signalDeclarations.emplace_back(Utils::SmallString{qmlMethod.methodName()},
+ createParameters(qmlMethod));
+ }
+ }
+
+ return functionAndSignalDeclarations;
+}
+
+Storage::EnumeratorDeclarations createEnumeratorsWithValues(const QQmlJSMetaEnum &qmlEnumeration)
+{
+ Storage::EnumeratorDeclarations enumeratorDeclarations;
+
+ const QStringList &keys = qmlEnumeration.keys();
+ const QList<int> &values = qmlEnumeration.values();
+ auto currentKey = keys.begin();
+ auto currentValue = values.begin();
+ auto keyEnd = keys.end();
+ auto valueEnd = values.end();
+
+ for (; currentKey != keyEnd && currentValue != valueEnd; ++currentKey, ++currentValue)
+ enumeratorDeclarations.emplace_back(Utils::SmallString{*currentKey}, *currentValue);
+
+ return enumeratorDeclarations;
+}
+
+Storage::EnumeratorDeclarations createEnumeratorsWithoutValues(const QQmlJSMetaEnum &qmlEnumeration)
+{
+ Storage::EnumeratorDeclarations enumeratorDeclarations;
+
+ for (const QString &key : qmlEnumeration.keys())
+ enumeratorDeclarations.emplace_back(Utils::SmallString{key});
+
+ return enumeratorDeclarations;
+}
+
+Storage::EnumeratorDeclarations createEnumerators(const QQmlJSMetaEnum &qmlEnumeration)
+{
+ if (qmlEnumeration.hasValues())
+ return createEnumeratorsWithValues(qmlEnumeration);
+
+ return createEnumeratorsWithoutValues(qmlEnumeration);
+}
+
+Storage::EnumerationDeclarations createEnumeration(const QHash<QString, QQmlJSMetaEnum> &qmlEnumerations)
+{
+ Storage::EnumerationDeclarations enumerationDeclarations;
+ enumerationDeclarations.reserve(Utils::usize(qmlEnumerations));
+
+ for (const QQmlJSMetaEnum &qmlEnumeration : qmlEnumerations) {
+ enumerationDeclarations.emplace_back(Utils::SmallString{qmlEnumeration.name()},
+ createEnumerators(qmlEnumeration));
+ }
+
+ return enumerationDeclarations;
+}
+
+void addType(Storage::Types &types,
+ SourceId sourceId,
+ ModuleId cppModuleId,
+ const QQmlJSScope &component,
+ QmlTypesParser::ProjectStorage &storage)
+{
+ auto [functionsDeclarations, signalDeclarations] = createFunctionAndSignals(component.ownMethods());
+ types.emplace_back(Utils::SmallString{component.internalName()},
+ Storage::NativeType{Utils::SmallString{component.baseTypeName()}},
+ createTypeAccessSemantics(component.accessSemantics()),
+ sourceId,
+ createExports(component.exports(), component, storage, cppModuleId),
+ createProperties(component.ownProperties()),
+ std::move(functionsDeclarations),
+ std::move(signalDeclarations),
+ createEnumeration(component.ownEnumerations()));
+}
+
+void addTypes(Storage::Types &types,
+ const Storage::ProjectData &projectData,
+ const QHash<QString, QQmlJSScope::Ptr> &objects,
+ QmlTypesParser::ProjectStorage &storage)
+{
+ types.reserve(Utils::usize(objects) + types.size());
+
+ for (const auto &object : objects)
+ addType(types, projectData.sourceId, projectData.extraModuleId, *object.get(), storage);
+}
+
+} // namespace
+
+void QmlTypesParser::parse(const QString &sourceContent,
+ Storage::Imports &imports,
+ Storage::Types &types,
+ const Storage::ProjectData &projectData)
+{
+ QQmlJSTypeDescriptionReader reader({}, sourceContent);
+ QHash<QString, QQmlJSScope::Ptr> components;
+ QStringList dependencies;
+ bool isValid = reader(&components, &dependencies);
+ if (!isValid)
+ throw CannotParseQmlTypesFile{};
+
+ addImports(imports, projectData.sourceId, dependencies, m_storage);
+ addTypes(types, projectData, components, m_storage);
+}
+
+} // namespace QmlDesigner
diff --git a/src/plugins/qmldesigner/designercore/projectstorage/qmltypesparser.h b/src/plugins/qmldesigner/designercore/projectstorage/qmltypesparser.h
new file mode 100644
index 0000000000..40f88d240d
--- /dev/null
+++ b/src/plugins/qmldesigner/designercore/projectstorage/qmltypesparser.h
@@ -0,0 +1,63 @@
+/****************************************************************************
+**
+** Copyright (C) 2021 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 "nonlockingmutex.h"
+#include "qmltypesparserinterface.h"
+
+namespace Sqlite {
+class Database;
+}
+
+namespace QmlDesigner {
+
+template<typename Database>
+class ProjectStorage;
+
+template<typename ProjectStorage, typename Mutex>
+class SourcePathCache;
+
+class QmlTypesParser : public QmlTypesParserInterface
+{
+public:
+ using ProjectStorage = QmlDesigner::ProjectStorage<Sqlite::Database>;
+ using PathCache = QmlDesigner::SourcePathCache<ProjectStorage, NonLockingMutex>;
+
+ QmlTypesParser(PathCache &pathCache, ProjectStorage &storage)
+ : m_pathCache{pathCache}
+ , m_storage{storage}
+ {}
+
+ void parse(const QString &sourceContent,
+ Storage::Imports &imports,
+ Storage::Types &types,
+ const Storage::ProjectData &projectData) override;
+
+private:
+ PathCache &m_pathCache;
+ ProjectStorage &m_storage;
+};
+} // namespace QmlDesigner
diff --git a/src/plugins/qmldesigner/designercore/projectstorage/qmltypesparserinterface.h b/src/plugins/qmldesigner/designercore/projectstorage/qmltypesparserinterface.h
index 40c9883835..3255c0b5aa 100644
--- a/src/plugins/qmldesigner/designercore/projectstorage/qmltypesparserinterface.h
+++ b/src/plugins/qmldesigner/designercore/projectstorage/qmltypesparserinterface.h
@@ -37,7 +37,7 @@ public:
virtual void parse(const QString &sourceContent,
Storage::Imports &imports,
Storage::Types &types,
- SourceIds &sourceIds)
+ const Storage::ProjectData &projectData)
= 0;
protected:
diff --git a/src/plugins/qmldesigner/generatecmakelists.cpp b/src/plugins/qmldesigner/generatecmakelists.cpp
new file mode 100644
index 0000000000..8e96c0ec95
--- /dev/null
+++ b/src/plugins/qmldesigner/generatecmakelists.cpp
@@ -0,0 +1,272 @@
+/****************************************************************************
+**
+** Copyright (C) 2021 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt Design Tooling
+**
+** 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 "generatecmakelists.h"
+
+#include <coreplugin/actionmanager/actionmanager.h>
+#include <coreplugin/actionmanager/actioncontainer.h>
+
+#include <projectexplorer/projectexplorerconstants.h>
+#include <projectexplorer/project.h>
+#include <projectexplorer/session.h>
+
+#include <qmlprojectmanager/qmlprojectmanagerconstants.h>
+
+#include <utils/fileutils.h>
+
+#include <QAction>
+#include <QRegularExpression>
+#include <QStringList>
+#include <QTextStream>
+
+using namespace Utils;
+
+namespace QmlDesigner {
+namespace GenerateCmakeLists {
+
+const QDir::Filters FILES_ONLY = QDir::Files;
+const QDir::Filters DIRS_ONLY = QDir::Dirs|QDir::Readable|QDir::NoDotAndDotDot;
+
+const char CMAKEFILENAME[] = "CMakeLists.txt";
+const char QMLDIRFILENAME[] = "qmldir";
+
+void generateMenuEntry()
+{
+ Core::ActionContainer *buildMenu =
+ Core::ActionManager::actionContainer(ProjectExplorer::Constants::M_BUILDPROJECT);
+ const Core::Context projectCntext(QmlProjectManager::Constants::QML_PROJECT_ID);
+ auto action = new QAction("Generate CMakeLists.txt files");
+ QObject::connect(action, &QAction::triggered, GenerateCmakeLists::onGenerateCmakeLists);
+ Core::Command *cmd = Core::ActionManager::registerAction(action, "QmlProject.CreateCMakeLists");
+ buildMenu->addAction(cmd, ProjectExplorer::Constants::G_BUILD_RUN);
+
+ action->setEnabled(ProjectExplorer::SessionManager::startupProject() != nullptr);
+ QObject::connect(ProjectExplorer::SessionManager::instance(),
+ &ProjectExplorer::SessionManager::startupProjectChanged, [action]() {
+ action->setEnabled(ProjectExplorer::SessionManager::startupProject() != nullptr);
+ });
+}
+
+void onGenerateCmakeLists()
+{
+ generateMainCmake(ProjectExplorer::SessionManager::startupProject()->projectDirectory());
+}
+
+QStringList processDirectory(const FilePath &dir)
+{
+ QStringList moduleNames;
+
+ FilePaths files = dir.dirEntries(FILES_ONLY);
+ for (FilePath &file : files) {
+ if (!file.fileName().compare(CMAKEFILENAME))
+ files.removeAll(file);
+ }
+
+ if (files.isEmpty()) {
+ generateSubdirCmake(dir);
+ FilePaths subDirs = dir.dirEntries(DIRS_ONLY);
+ for (FilePath &subDir : subDirs) {
+ QStringList subDirModules = processDirectory(subDir);
+ moduleNames.append(subDirModules);
+ }
+ }
+ else {
+ QString moduleName = generateModuleCmake(dir);
+ if (!moduleName.isEmpty()) {
+ moduleNames.append(moduleName);
+ }
+ }
+
+ return moduleNames;
+}
+
+const char MAINFILE_REQUIRED_VERSION[] = "cmake_minimum_required(VERSION 3.18)\n\n";
+const char MAINFILE_PROJECT[] = "project(%1 LANGUAGES CXX)\n\n";
+const char MAINFILE_CMAKE_OPTIONS[] = "set(CMAKE_INCLUDE_CURRENT_DIR ON)\nset(CMAKE_AUTOMOC ON)\n\n";
+const char MAINFILE_PACKAGES[] = "find_package(Qt6 COMPONENTS Gui Qml Quick)\n";
+const char MAINFILE_LIBRARIES[] = "set(QT_QML_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/qml)\n\n";
+const char MAINFILE_CPP[] = "add_executable(%1 main.cpp)\n\n";
+const char MAINFILE_MAINMODULE[] = "qt6_add_qml_module(%1\n\tURI \"Main\"\n\tVERSION 1.0\n\tNO_PLUGIN\n\tQML_FILES main.qml\n)\n\n";
+const char MAINFILE_LINK_LIBRARIES[] = "target_link_libraries(%1 PRIVATE\n\tQt${QT_VERSION_MAJOR}::Core\n\tQt${QT_VERSION_MAJOR}::Gui\n\tQt${QT_VERSION_MAJOR}::Quick\n\tQt${QT_VERSION_MAJOR}::Qml\n)\n\n";
+
+const char ADD_SUBDIR[] = "add_subdirectory(%1)\n";
+
+void generateMainCmake(const FilePath &rootDir)
+{
+ //TODO startupProject() may be a terrible way to try to get "current project". It's not necessarily the same thing at all.
+ QString projectName = ProjectExplorer::SessionManager::startupProject()->displayName();
+
+ FilePaths subDirs = rootDir.dirEntries(DIRS_ONLY);
+
+ QString fileContent;
+ fileContent.append(MAINFILE_REQUIRED_VERSION);
+ fileContent.append(QString(MAINFILE_PROJECT).arg(projectName));
+ fileContent.append(MAINFILE_CMAKE_OPTIONS);
+ fileContent.append(MAINFILE_PACKAGES);
+ fileContent.append(QString(MAINFILE_CPP).arg(projectName));
+ fileContent.append(QString(MAINFILE_MAINMODULE).arg(projectName));
+ fileContent.append(MAINFILE_LIBRARIES);
+
+ for (FilePath &subDir : subDirs) {
+ QStringList subDirModules = processDirectory(subDir);
+ if (!subDirModules.isEmpty())
+ fileContent.append(QString(ADD_SUBDIR).arg(subDir.fileName()));
+ }
+ fileContent.append("\n");
+
+ fileContent.append(QString(MAINFILE_LINK_LIBRARIES).arg(projectName));
+
+ createCmakeFile(rootDir, fileContent);
+}
+
+const char MODULEFILE_PROPERTY_SINGLETON[] = "QT_QML_SINGLETON_TYPE";
+const char MODULEFILE_PROPERTY_SET[] = "set_source_files_properties(%1\n\tPROPERTIES\n\t\t%2 %3\n)\n\n";
+const char MODULEFILE_CREATE_MODULE[] = "qt6_add_qml_module(%1\n\tURI \"%1\"\n\tVERSION 1.0\n%2)\n\n";
+
+
+QString generateModuleCmake(const FilePath &dir)
+{
+ QString fileContent;
+ const QStringList qmlFilesOnly("*.qml");
+ const QStringList qmldirFilesOnly(QMLDIRFILENAME);
+ ProjectExplorer::Project *project = ProjectExplorer::SessionManager::startupProject();
+
+ FilePaths qmldirFileList = dir.dirEntries(qmldirFilesOnly, FILES_ONLY);
+ if (!qmldirFileList.isEmpty()) {
+ QStringList singletons = getSingletonsFromQmldirFile(qmldirFileList.first());
+ for (QString &singleton : singletons) {
+ fileContent.append(QString(MODULEFILE_PROPERTY_SET).arg(singleton).arg(MODULEFILE_PROPERTY_SINGLETON).arg("true"));
+ }
+ }
+
+ FilePaths qmlFileList = dir.dirEntries(qmlFilesOnly, FILES_ONLY);
+ QString qmlFiles;
+ for (FilePath &qmlFile : qmlFileList) {
+ if (project->isKnownFile(qmlFile))
+ qmlFiles.append(QString("\t\t%1\n").arg(qmlFile.fileName()));
+ }
+
+ QStringList resourceFileList = getDirectoryTreeResources(dir);
+ QString resourceFiles;
+ for (QString &resourceFile : resourceFileList) {
+ resourceFiles.append(QString("\t\t%1\n").arg(resourceFile));
+ }
+
+ QString moduleContent;
+ if (!qmlFiles.isEmpty()) {
+ moduleContent.append(QString("\tQML_FILES\n%1").arg(qmlFiles));
+ }
+ if (!resourceFiles.isEmpty()) {
+ moduleContent.append(QString("\tRESOURCES\n%1").arg(resourceFiles));
+ }
+
+ QString moduleName = dir.fileName();
+
+ fileContent.append(QString(MODULEFILE_CREATE_MODULE).arg(moduleName).arg(moduleContent));
+
+ createCmakeFile(dir, fileContent);
+
+ return moduleName;
+}
+
+void generateSubdirCmake(const FilePath &dir)
+{
+ QString fileContent;
+ FilePaths subDirs = dir.dirEntries(DIRS_ONLY);
+
+ for (FilePath &subDir : subDirs) {
+ fileContent.append(QString(ADD_SUBDIR).arg(subDir.fileName()));
+ }
+
+ createCmakeFile(dir, fileContent);
+}
+
+QStringList getSingletonsFromQmldirFile(const FilePath &filePath)
+{
+ QStringList singletons;
+ QFile f(filePath.toString());
+ f.open(QIODevice::ReadOnly);
+ QTextStream stream(&f);
+
+ while (!stream.atEnd()) {
+ QString line = stream.readLine();
+ if (line.startsWith("singleton", Qt::CaseInsensitive)) {
+ QStringList tokenizedLine = line.split(QRegularExpression("\\s+"));
+ QString fileName = tokenizedLine.last();
+ if (fileName.endsWith(".qml", Qt::CaseInsensitive)) {
+ singletons.append(fileName);
+ }
+ }
+ }
+
+ f.close();
+
+ return singletons;
+}
+
+QStringList getDirectoryTreeResources(const FilePath &dir)
+{
+ ProjectExplorer::Project *project = ProjectExplorer::SessionManager::startupProject();
+ QStringList resourceFileList;
+
+ FilePaths thisDirFiles = dir.dirEntries(FILES_ONLY);
+ for (FilePath &file : thisDirFiles) {
+ if (!isFileBlacklisted(file.fileName()) &&
+ !file.fileName().endsWith(".qml", Qt::CaseInsensitive) &&
+ project->isKnownFile(file)) {
+ resourceFileList.append(file.fileName());
+ }
+ }
+
+ FilePaths subDirsList = dir.dirEntries(DIRS_ONLY);
+ for (FilePath &subDir : subDirsList) {
+ QStringList subDirResources = getDirectoryTreeResources(subDir);
+ for (QString &resource : subDirResources) {
+ resourceFileList.append(subDir.fileName().append('/').append(resource));
+ }
+
+ }
+
+ return resourceFileList;
+}
+
+void createCmakeFile(const FilePath &dir, const QString &content)
+{
+ FilePath filePath = dir.pathAppended(CMAKEFILENAME);
+ QFile cmakeFile(filePath.toString());
+ cmakeFile.open(QIODevice::WriteOnly);
+ QTextStream stream(&cmakeFile);
+ stream << content;
+ cmakeFile.close();
+}
+
+bool isFileBlacklisted(const QString &fileName)
+{
+ return (!fileName.compare(QMLDIRFILENAME) ||
+ !fileName.compare(CMAKEFILENAME));
+}
+
+}
+}
diff --git a/src/plugins/qmldesigner/generatecmakelists.h b/src/plugins/qmldesigner/generatecmakelists.h
new file mode 100644
index 0000000000..55b0f6958d
--- /dev/null
+++ b/src/plugins/qmldesigner/generatecmakelists.h
@@ -0,0 +1,45 @@
+/****************************************************************************
+**
+** Copyright (C) 2021 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt Design Tooling
+**
+** 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 <projectexplorer/project.h>
+
+#include <utils/fileutils.h>
+
+namespace QmlDesigner {
+namespace GenerateCmakeLists {
+void generateMenuEntry();
+void onGenerateCmakeLists();
+void generateMainCmake(const Utils::FilePath &rootDir);
+void generateSubdirCmake(const Utils::FilePath &dir);
+QString generateModuleCmake(const Utils::FilePath &dir);
+QStringList processDirectory(const Utils::FilePath &dir);
+QStringList getSingletonsFromQmldirFile(const Utils::FilePath &filePath);
+QStringList getDirectoryTreeResources(const Utils::FilePath &dir);
+void createCmakeFile(const Utils::FilePath &filePath, const QString &content);
+bool isFileBlacklisted(const QString &fileName);
+}
+}
diff --git a/src/plugins/qmldesigner/qmldesignerplugin.cpp b/src/plugins/qmldesigner/qmldesignerplugin.cpp
index 77c4715f17..014c79b59d 100644
--- a/src/plugins/qmldesigner/qmldesignerplugin.cpp
+++ b/src/plugins/qmldesigner/qmldesignerplugin.cpp
@@ -31,6 +31,7 @@
#include "designmodecontext.h"
#include "openuiqmlfiledialog.h"
#include "generateresource.h"
+#include "generatecmakelists.h"
#include "nodeinstanceview.h"
#include "gestures.h"
@@ -222,6 +223,8 @@ bool QmlDesignerPlugin::initialize(const QStringList & /*arguments*/, QString *e
if (DesignerSettings::getValue(DesignerSettingsKey::STANDALONE_MODE).toBool())
GenerateResource::generateMenuEntry();
+ GenerateCmakeLists::generateMenuEntry();
+
const QString fontPath
= Core::ICore::resourcePath(
"qmldesigner/propertyEditorQmlSources/imports/StudioTheme/icons.ttf")
diff --git a/src/plugins/qmldesigner/qmldesignerplugin.pri b/src/plugins/qmldesigner/qmldesignerplugin.pri
index 58fb55788f..4cf7edf4ba 100644
--- a/src/plugins/qmldesigner/qmldesignerplugin.pri
+++ b/src/plugins/qmldesigner/qmldesignerplugin.pri
@@ -5,6 +5,7 @@ HEADERS += $$PWD/qmldesignerconstants.h \
$$PWD/designersettings.h \
$$PWD/editorproxy.h \
$$PWD/generateresource.h \
+ $$PWD/generatecmakelists.h \
$$PWD/settingspage.h \
$$PWD/designmodecontext.h \
$$PWD/documentmanager.h \
@@ -20,6 +21,7 @@ SOURCES += $$PWD/qmldesignerplugin.cpp \
$$PWD/designersettings.cpp \
$$PWD/editorproxy.cpp \
$$PWD/generateresource.cpp \
+ $$PWD/generatecmakelists.cpp \
$$PWD/settingspage.cpp \
$$PWD/designmodecontext.cpp \
$$PWD/documentmanager.cpp \
diff --git a/src/plugins/qmldesigner/qmldesignerplugin.qbs b/src/plugins/qmldesigner/qmldesignerplugin.qbs
index a1cf95c0e8..a3b70ec970 100644
--- a/src/plugins/qmldesigner/qmldesignerplugin.qbs
+++ b/src/plugins/qmldesigner/qmldesignerplugin.qbs
@@ -1007,6 +1007,8 @@ Project {
files: [
"generateresource.cpp",
"generateresource.h",
+ "generatecmakelists.cpp",
+ "generatecmakelists.h",
"designersettings.cpp",
"designersettings.h",
"designmodecontext.cpp",
diff --git a/src/plugins/qmldesigner/qtquickplugin/images/component-icon.png b/src/plugins/qmldesigner/qtquickplugin/images/component-icon.png
new file mode 100644
index 0000000000..9c7df42bc7
--- /dev/null
+++ b/src/plugins/qmldesigner/qtquickplugin/images/component-icon.png
Binary files differ
diff --git a/src/plugins/qmldesigner/qtquickplugin/images/component-icon16.png b/src/plugins/qmldesigner/qtquickplugin/images/component-icon16.png
new file mode 100644
index 0000000000..99941541c6
--- /dev/null
+++ b/src/plugins/qmldesigner/qtquickplugin/images/component-icon16.png
Binary files differ
diff --git a/src/plugins/qmldesigner/qtquickplugin/images/component-icon@2x.png b/src/plugins/qmldesigner/qtquickplugin/images/component-icon@2x.png
new file mode 100644
index 0000000000..f66349a63b
--- /dev/null
+++ b/src/plugins/qmldesigner/qtquickplugin/images/component-icon@2x.png
Binary files differ
diff --git a/src/plugins/qmldesigner/qtquickplugin/images/loader-icon.png b/src/plugins/qmldesigner/qtquickplugin/images/loader-icon.png
new file mode 100644
index 0000000000..29082eacf1
--- /dev/null
+++ b/src/plugins/qmldesigner/qtquickplugin/images/loader-icon.png
Binary files differ
diff --git a/src/plugins/qmldesigner/qtquickplugin/images/loader-icon16.png b/src/plugins/qmldesigner/qtquickplugin/images/loader-icon16.png
new file mode 100644
index 0000000000..4a2b093259
--- /dev/null
+++ b/src/plugins/qmldesigner/qtquickplugin/images/loader-icon16.png
Binary files differ
diff --git a/src/plugins/qmldesigner/qtquickplugin/images/loader-icon@2x.png b/src/plugins/qmldesigner/qtquickplugin/images/loader-icon@2x.png
new file mode 100644
index 0000000000..750b13bd02
--- /dev/null
+++ b/src/plugins/qmldesigner/qtquickplugin/images/loader-icon@2x.png
Binary files differ
diff --git a/src/plugins/qmldesigner/qtquickplugin/images/repeater-icon.png b/src/plugins/qmldesigner/qtquickplugin/images/repeater-icon.png
new file mode 100644
index 0000000000..efe3ca80b4
--- /dev/null
+++ b/src/plugins/qmldesigner/qtquickplugin/images/repeater-icon.png
Binary files differ
diff --git a/src/plugins/qmldesigner/qtquickplugin/images/repeater-icon16.png b/src/plugins/qmldesigner/qtquickplugin/images/repeater-icon16.png
new file mode 100644
index 0000000000..775a57a38c
--- /dev/null
+++ b/src/plugins/qmldesigner/qtquickplugin/images/repeater-icon16.png
Binary files differ
diff --git a/src/plugins/qmldesigner/qtquickplugin/images/repeater-icon@2x.png b/src/plugins/qmldesigner/qtquickplugin/images/repeater-icon@2x.png
new file mode 100644
index 0000000000..bb541b6711
--- /dev/null
+++ b/src/plugins/qmldesigner/qtquickplugin/images/repeater-icon@2x.png
Binary files differ
diff --git a/src/plugins/qmldesigner/qtquickplugin/qtquickplugin.qrc b/src/plugins/qmldesigner/qtquickplugin/qtquickplugin.qrc
index be1770378b..8adfb84baf 100644
--- a/src/plugins/qmldesigner/qtquickplugin/qtquickplugin.qrc
+++ b/src/plugins/qmldesigner/qtquickplugin/qtquickplugin.qrc
@@ -72,5 +72,14 @@
<file>images/animated-image-icon.png</file>
<file>images/animated-image-icon@2x.png</file>
<file>images/animated-image-icon16.png</file>
+ <file>images/component-icon.png</file>
+ <file>images/component-icon@2x.png</file>
+ <file>images/component-icon16.png</file>
+ <file>images/repeater-icon.png</file>
+ <file>images/repeater-icon@2x.png</file>
+ <file>images/repeater-icon16.png</file>
+ <file>images/loader-icon.png</file>
+ <file>images/loader-icon@2x.png</file>
+ <file>images/loader-icon16.png</file>
</qresource>
</RCC>
diff --git a/src/plugins/qmldesigner/qtquickplugin/quick.metainfo b/src/plugins/qmldesigner/qtquickplugin/quick.metainfo
index 019be09973..851d457cdc 100644
--- a/src/plugins/qmldesigner/qtquickplugin/quick.metainfo
+++ b/src/plugins/qmldesigner/qtquickplugin/quick.metainfo
@@ -434,7 +434,7 @@ MetaInfo {
Type {
name: "QtQml.Component"
- icon: ":/qtquickplugin/images/item-icon16.png"
+ icon: ":/qtquickplugin/images/component-icon16.png"
Hints {
canBeDroppedInNavigator: true
@@ -444,19 +444,19 @@ MetaInfo {
ItemLibraryEntry {
name: "Component"
category: "e.Qt Quick - Component"
- libraryIcon: ":/qtquickplugin/images/item-icon.png"
+ libraryIcon: ":/qtquickplugin/images/component-icon.png"
version: "2.0"
}
}
Type {
name: "QtQuick.Loader"
- icon: ":/qtquickplugin/images/item-icon16.png"
+ icon: ":/qtquickplugin/images/loader-icon16.png"
ItemLibraryEntry {
name: "Loader"
category: "e.Qt Quick - Component"
- libraryIcon: ":/qtquickplugin/images/item-icon.png"
+ libraryIcon: ":/qtquickplugin/images/loader-icon.png"
version: "2.0"
Property { name: "width"; type: "int"; value: 200; }
Property { name: "height"; type: "int"; value: 200; }
@@ -465,7 +465,7 @@ MetaInfo {
Type {
name: "QtQuick.Repeater"
- icon: ":/qtquickplugin/images/item-icon16.png"
+ icon: ":/qtquickplugin/images/repeater-icon16.png"
Hints {
canBeDroppedInFormEditor: false
@@ -475,7 +475,7 @@ MetaInfo {
ItemLibraryEntry {
name: "Repeater"
category: "e.Qt Quick - Component"
- libraryIcon: ":/qtquickplugin/images/item-icon.png"
+ libraryIcon: ":/qtquickplugin/images/repeater-icon.png"
version: "2.0"
}
}
diff --git a/src/plugins/qmlpreview/qmldebugtranslationclient.cpp b/src/plugins/qmlpreview/qmldebugtranslationclient.cpp
index e383784ef5..5d48877265 100644
--- a/src/plugins/qmlpreview/qmldebugtranslationclient.cpp
+++ b/src/plugins/qmlpreview/qmldebugtranslationclient.cpp
@@ -52,14 +52,6 @@ void QmlDebugTranslationClient::changeLanguage(const QUrl &url, const QString &l
}
-void QmlDebugTranslationClient::messageReceived(const QByteArray &data)
-{
- QmlDebug::QPacket packet(dataStreamVersion(), data);
- qint8 command;
- packet >> command;
- qDebug() << Q_FUNC_INFO << "invalid command" << command;
-}
-
void QmlDebugTranslationClient::stateChanged(QmlDebug::QmlDebugClient::State state)
{
if (state == Unavailable)
diff --git a/src/plugins/qmlpreview/qmldebugtranslationclient.h b/src/plugins/qmlpreview/qmldebugtranslationclient.h
index 0b9e3594b2..8a6bc1478f 100644
--- a/src/plugins/qmlpreview/qmldebugtranslationclient.h
+++ b/src/plugins/qmlpreview/qmldebugtranslationclient.h
@@ -37,8 +37,6 @@ public:
explicit QmlDebugTranslationClient(QmlDebug::QmlDebugConnection *connection);
void changeLanguage(const QUrl &url, const QString &localeIsoCode);
-
- void messageReceived(const QByteArray &message) override;
void stateChanged(State state) override;
signals:
diff --git a/src/plugins/qmlprofiler/qmlprofilertraceclient.cpp b/src/plugins/qmlprofiler/qmlprofilertraceclient.cpp
index 054cc31eae..8dcd41cbb4 100644
--- a/src/plugins/qmlprofiler/qmlprofilertraceclient.cpp
+++ b/src/plugins/qmlprofiler/qmlprofilertraceclient.cpp
@@ -36,7 +36,7 @@
namespace QmlProfiler {
-inline uint qHash(const QmlEventType &type)
+inline auto qHash(const QmlEventType &type)
{
return qHash(type.location())
^ (((type.message() << 12) & 0xf000) // 4 bits of message
diff --git a/src/plugins/qmlprojectmanager/fileformat/qmlprojectfileformat.cpp b/src/plugins/qmlprojectmanager/fileformat/qmlprojectfileformat.cpp
index 53c76263a2..962b403492 100644
--- a/src/plugins/qmlprojectmanager/fileformat/qmlprojectfileformat.cpp
+++ b/src/plugins/qmlprojectmanager/fileformat/qmlprojectfileformat.cpp
@@ -99,6 +99,14 @@ QmlProjectItem *QmlProjectFileFormat::parseProjectFile(const Utils::FilePath &fi
if (fileSelectorsProperty.isValid())
projectItem->setFileSelectors(fileSelectorsProperty.value.toStringList());
+ const auto languagesProperty = rootNode->property(QLatin1String("supportedLanguages"));
+ if (languagesProperty.isValid())
+ projectItem->setSupportedLanguages(languagesProperty.value.toStringList());
+
+ const auto primaryLanguageProperty = rootNode->property(QLatin1String("primaryLanguage"));
+ if (primaryLanguageProperty.isValid())
+ projectItem->setPrimaryLanguage(primaryLanguageProperty.value.toString());
+
const auto forceFreeTypeProperty = rootNode->property("forceFreeType");
if (forceFreeTypeProperty.isValid())
projectItem->setForceFreeType(forceFreeTypeProperty.value.toBool());
diff --git a/src/plugins/qmlprojectmanager/fileformat/qmlprojectitem.cpp b/src/plugins/qmlprojectmanager/fileformat/qmlprojectitem.cpp
index b7aa7ec434..249474a224 100644
--- a/src/plugins/qmlprojectmanager/fileformat/qmlprojectitem.cpp
+++ b/src/plugins/qmlprojectmanager/fileformat/qmlprojectitem.cpp
@@ -77,6 +77,18 @@ void QmlProjectItem::setFileSelectors(const QStringList &selectors)
m_fileSelectors = selectors;
}
+void QmlProjectItem::setSupportedLanguages(const QStringList &languages)
+{
+ if (m_supportedLanguages != languages)
+ m_supportedLanguages = languages;
+}
+
+void QmlProjectItem::setPrimaryLanguage(const QString &language)
+{
+ if (m_primaryLanguage != language)
+ m_primaryLanguage = language;
+}
+
/* Returns list of absolute paths */
QStringList QmlProjectItem::files() const
{
diff --git a/src/plugins/qmlprojectmanager/fileformat/qmlprojectitem.h b/src/plugins/qmlprojectmanager/fileformat/qmlprojectitem.h
index 2f0f8786ef..90d17e4859 100644
--- a/src/plugins/qmlprojectmanager/fileformat/qmlprojectitem.h
+++ b/src/plugins/qmlprojectmanager/fileformat/qmlprojectitem.h
@@ -63,6 +63,12 @@ public:
QStringList fileSelectors() const { return m_fileSelectors; }
void setFileSelectors(const QStringList &selectors);
+ QStringList supportedLanguages() const { return m_supportedLanguages; }
+ void setSupportedLanguages(const QStringList &languages);
+
+ QString primaryLanguage() const { return m_primaryLanguage; }
+ void setPrimaryLanguage(const QString &language);
+
QStringList files() const;
bool matchesFile(const QString &filePath) const;
@@ -85,6 +91,8 @@ protected:
QString m_targetDirectory;
QStringList m_importPaths;
QStringList m_fileSelectors;
+ QStringList m_supportedLanguages;
+ QString m_primaryLanguage;
QString m_mainFile;
Utils::EnvironmentItems m_environment;
QVector<QmlProjectContentItem *> m_content; // content property
diff --git a/src/plugins/qmlprojectmanager/qmlmultilanguageaspect.cpp b/src/plugins/qmlprojectmanager/qmlmultilanguageaspect.cpp
index dc8940844b..662e904974 100644
--- a/src/plugins/qmlprojectmanager/qmlmultilanguageaspect.cpp
+++ b/src/plugins/qmlprojectmanager/qmlmultilanguageaspect.cpp
@@ -46,8 +46,7 @@ static bool isMultilanguagePresent()
static Utils::FilePath getMultilanguageDatabaseFilePath(ProjectExplorer::Target *target)
{
if (target) {
- auto filePath = target->project()->projectDirectory().pathAppended(
- "multilanguage-experimental-v6.db");
+ auto filePath = target->project()->projectDirectory().pathAppended("translations.db");
if (filePath.exists())
return filePath;
}
diff --git a/src/plugins/qmlprojectmanager/qmlproject.cpp b/src/plugins/qmlprojectmanager/qmlproject.cpp
index c1b8c6dc43..876fa4e188 100644
--- a/src/plugins/qmlprojectmanager/qmlproject.cpp
+++ b/src/plugins/qmlprojectmanager/qmlproject.cpp
@@ -340,6 +340,20 @@ QStringList QmlBuildSystem::customFileSelectors() const
return {};
}
+QStringList QmlBuildSystem::supportedLanguages() const
+{
+ if (m_projectItem)
+ return m_projectItem.data()->supportedLanguages();
+ return {};
+}
+
+QString QmlBuildSystem::primaryLanguage() const
+{
+ if (m_projectItem)
+ return m_projectItem.data()->primaryLanguage();
+ return {};
+}
+
void QmlBuildSystem::refreshProjectFile()
{
refresh(QmlBuildSystem::ProjectFile | Files);
@@ -509,6 +523,10 @@ QVariant QmlBuildSystem::additionalData(Id id) const
{
if (id == Constants::customFileSelectorsData)
return customFileSelectors();
+ if (id == Constants::supportedLanguagesData)
+ return supportedLanguages();
+ if (id == Constants::primaryLanguageData)
+ return primaryLanguage();
if (id == Constants::customForceFreeTypeData)
return forceFreeType();
if (id == Constants::customQtForMCUs)
diff --git a/src/plugins/qmlprojectmanager/qmlproject.h b/src/plugins/qmlprojectmanager/qmlproject.h
index 51028b0d54..64c0cc90ec 100644
--- a/src/plugins/qmlprojectmanager/qmlproject.h
+++ b/src/plugins/qmlprojectmanager/qmlproject.h
@@ -88,6 +88,8 @@ public:
Utils::EnvironmentItems environment() const;
QStringList customImportPaths() const;
QStringList customFileSelectors() const;
+ QStringList supportedLanguages() const;
+ QString primaryLanguage() const;
bool forceFreeType() const;
bool addFiles(const QStringList &filePaths);
diff --git a/src/plugins/qmlprojectmanager/qmlprojectconstants.h b/src/plugins/qmlprojectmanager/qmlprojectconstants.h
index 7a8df1f4f8..184469f243 100644
--- a/src/plugins/qmlprojectmanager/qmlprojectconstants.h
+++ b/src/plugins/qmlprojectmanager/qmlprojectconstants.h
@@ -32,6 +32,8 @@ namespace Constants {
const char * const QMLPROJECT_MIMETYPE = QmlJSTools::Constants::QMLPROJECT_MIMETYPE;
const char customFileSelectorsData[] = "CustomFileSelectorsData";
+const char supportedLanguagesData[] = "SupportedLanguagesData";
+const char primaryLanguageData[] = "PrimaryLanguageData";
const char customForceFreeTypeData[] = "CustomForceFreeType";
const char customQtForMCUs[] = "CustomQtForMCUs";
const char customQt6Project[] = "CustomQt6Project";
diff --git a/src/plugins/remotelinux/deploymenttimeinfo.cpp b/src/plugins/remotelinux/deploymenttimeinfo.cpp
index 3130aadf20..81eb9417e3 100644
--- a/src/plugins/remotelinux/deploymenttimeinfo.cpp
+++ b/src/plugins/remotelinux/deploymenttimeinfo.cpp
@@ -61,7 +61,7 @@ public:
QString sysroot;
};
-uint qHash(const DeployParameters &p) {
+auto qHash(const DeployParameters &p) {
return qHash(qMakePair(qMakePair(p.file, p.host), p.sysroot));
}
diff --git a/src/plugins/resourceeditor/resourceeditorplugin.cpp b/src/plugins/resourceeditor/resourceeditorplugin.cpp
index 62a4d75245..36de99ca39 100644
--- a/src/plugins/resourceeditor/resourceeditorplugin.cpp
+++ b/src/plugins/resourceeditor/resourceeditorplugin.cpp
@@ -46,6 +46,7 @@
#include <utils/algorithm.h>
#include <utils/parameteraction.h>
#include <utils/qtcassert.h>
+#include <utils/threadutils.h>
#include <QCoreApplication>
#include <QAction>
@@ -247,21 +248,35 @@ ResourceEditorPluginPrivate::ResourceEditorPluginPrivate(ResourceEditorPlugin *q
void ResourceEditorPlugin::extensionsInitialized()
{
- ProjectTree::registerTreeManager([](FolderNode *folder) {
- QList<FileNode *> toReplace;
- folder->forEachNode([&toReplace](FileNode *fn) {
- if (fn->fileType() == FileType::Resource)
- toReplace.append(fn);
- });
-
- for (FileNode *file : qAsConst(toReplace)) {
- FolderNode *const pn = file->parentFolderNode();
- QTC_ASSERT(pn, continue);
- const Utils::FilePath path = file->filePath();
- auto topLevel = std::make_unique<ResourceTopLevelNode>(path, pn->filePath());
- topLevel->setEnabled(file->isEnabled());
- topLevel->setIsGenerated(file->isGenerated());
- pn->replaceSubtree(file, std::move(topLevel));
+ ProjectTree::registerTreeManager([](FolderNode *folder, ProjectTree::ConstructionPhase phase) {
+ switch (phase) {
+ case ProjectTree::AsyncPhase: {
+ QList<FileNode *> toReplace;
+ folder->forEachNode([&toReplace](FileNode *fn) {
+ if (fn->fileType() == FileType::Resource)
+ toReplace.append(fn);
+ }, {}, [](const FolderNode *fn) {
+ return dynamic_cast<const ResourceTopLevelNode *>(fn) == nullptr;
+ });
+ for (FileNode *file : qAsConst(toReplace)) {
+ FolderNode *const pn = file->parentFolderNode();
+ QTC_ASSERT(pn, continue);
+ const Utils::FilePath path = file->filePath();
+ auto topLevel = std::make_unique<ResourceTopLevelNode>(path, pn->filePath());
+ topLevel->setEnabled(file->isEnabled());
+ topLevel->setIsGenerated(file->isGenerated());
+ pn->replaceSubtree(file, std::move(topLevel));
+ }
+ break;
+ }
+ case ProjectTree::FinalPhase: {
+ folder->forEachNode({}, [](FolderNode *fn) {
+ auto *topLevel = dynamic_cast<ResourceTopLevelNode *>(fn);
+ if (topLevel)
+ topLevel->setupWatcherIfNeeded();
+ });
+ break;
+ }
}
});
}
diff --git a/src/plugins/resourceeditor/resourcenode.cpp b/src/plugins/resourceeditor/resourcenode.cpp
index 30be6b0c0a..75f35da4d8 100644
--- a/src/plugins/resourceeditor/resourcenode.cpp
+++ b/src/plugins/resourceeditor/resourcenode.cpp
@@ -36,6 +36,7 @@
#include <utils/fileutils.h>
#include <utils/mimetypes/mimedatabase.h>
#include <utils/qtcassert.h>
+#include <utils/threadutils.h>
#include <QCoreApplication>
#include <QDir>
@@ -251,10 +252,8 @@ ResourceTopLevelNode::ResourceTopLevelNode(const FilePath &filePath,
setShowWhenEmpty(true);
if (!filePath.isEmpty()) {
- if (filePath.isReadableFile()) {
- m_document = new ResourceFileWatcher(this);
- DocumentManager::addDocument(m_document);
- }
+ if (filePath.isReadableFile())
+ setupWatcherIfNeeded();
} else {
m_contents = contents;
}
@@ -267,6 +266,15 @@ ResourceTopLevelNode::ResourceTopLevelNode(const FilePath &filePath,
addInternalNodes();
}
+void ResourceTopLevelNode::setupWatcherIfNeeded()
+{
+ if (m_document || !isMainThread())
+ return;
+
+ m_document = new ResourceFileWatcher(this);
+ DocumentManager::addDocument(m_document);
+}
+
ResourceTopLevelNode::~ResourceTopLevelNode()
{
if (m_document)
diff --git a/src/plugins/resourceeditor/resourcenode.h b/src/plugins/resourceeditor/resourcenode.h
index a992e267dc..03ae8039f0 100644
--- a/src/plugins/resourceeditor/resourcenode.h
+++ b/src/plugins/resourceeditor/resourcenode.h
@@ -39,6 +39,7 @@ public:
const QString &contents = {});
~ResourceTopLevelNode() override;
+ void setupWatcherIfNeeded();
void addInternalNodes();
bool supportsAction(ProjectExplorer::ProjectAction action, const Node *node) const override;
diff --git a/src/plugins/scxmleditor/scxmleditordocument.cpp b/src/plugins/scxmleditor/scxmleditordocument.cpp
index 22cf828589..2ce6669e68 100644
--- a/src/plugins/scxmleditor/scxmleditordocument.cpp
+++ b/src/plugins/scxmleditor/scxmleditordocument.cpp
@@ -147,6 +147,11 @@ bool ScxmlEditorDocument::reload(QString *errorString, ReloadFlag flag, ChangeTy
return success;
}
+bool ScxmlEditorDocument::supportsCodec(const QTextCodec *codec) const
+{
+ return codec == QTextCodec::codecForName("UTF-8");
+}
+
QString ScxmlEditorDocument::designWidgetContents() const
{
return m_designWidget->contents();
diff --git a/src/plugins/scxmleditor/scxmleditordocument.h b/src/plugins/scxmleditor/scxmleditordocument.h
index 587343a70b..f46d03f0a2 100644
--- a/src/plugins/scxmleditor/scxmleditordocument.h
+++ b/src/plugins/scxmleditor/scxmleditordocument.h
@@ -57,6 +57,7 @@ public:
bool isSaveAsAllowed() const override;
bool isModified() const override;
bool reload(QString *errorString, ReloadFlag flag, ChangeType type) override;
+ bool supportsCodec(const QTextCodec *codec) const override;
// Internal
Common::MainWidget *designWidget() const;
diff --git a/src/plugins/studiowelcome/CMakeLists.txt b/src/plugins/studiowelcome/CMakeLists.txt
index d22625e7c7..2ae3bdcc9a 100644
--- a/src/plugins/studiowelcome/CMakeLists.txt
+++ b/src/plugins/studiowelcome/CMakeLists.txt
@@ -1,4 +1,5 @@
add_qtc_plugin(StudioWelcome
+ CONDITION TARGET Qt5::QuickWidgets
DEPENDS Qt5::QuickWidgets
PLUGIN_DEPENDS Core ProjectExplorer QtSupport
DEFINES STUDIO_QML_PATH="${CMAKE_CURRENT_SOURCE_DIR}/qml/"
diff --git a/src/plugins/studiowelcome/studiowelcomeplugin.cpp b/src/plugins/studiowelcome/studiowelcomeplugin.cpp
index 52957d7192..d119567562 100644
--- a/src/plugins/studiowelcome/studiowelcomeplugin.cpp
+++ b/src/plugins/studiowelcome/studiowelcomeplugin.cpp
@@ -342,10 +342,6 @@ bool StudioWelcomePlugin::initialize(const QStringList &arguments, QString *erro
m_welcomeMode = new WelcomeMode;
- QFontDatabase::addApplicationFont(":/studiofonts/TitilliumWeb-Regular.ttf");
- QFont systemFont("Titillium Web", QApplication::font().pointSize());
- QApplication::setFont(systemFont);
-
m_removeSplashTimer.setSingleShot(true);
m_removeSplashTimer.setInterval(15000);
connect(&m_removeSplashTimer, &QTimer::timeout, this, [this] { closeSplashScreen(); });
diff --git a/src/plugins/texteditor/codeassist/genericproposalmodel.cpp b/src/plugins/texteditor/codeassist/genericproposalmodel.cpp
index 96492caadb..d0343b11bf 100644
--- a/src/plugins/texteditor/codeassist/genericproposalmodel.cpp
+++ b/src/plugins/texteditor/codeassist/genericproposalmodel.cpp
@@ -41,7 +41,7 @@
using namespace TextEditor;
QT_BEGIN_NAMESPACE
-uint qHash(const AssistProposalItem &item)
+auto qHash(const AssistProposalItem &item)
{
return qHash(item.text());
}
diff --git a/src/plugins/texteditor/fontsettings.cpp b/src/plugins/texteditor/fontsettings.cpp
index e35ed5c3b2..4c6df391ce 100644
--- a/src/plugins/texteditor/fontsettings.cpp
+++ b/src/plugins/texteditor/fontsettings.cpp
@@ -141,7 +141,7 @@ bool FontSettings::equals(const FontSettings &f) const
&& m_scheme == f.m_scheme;
}
-uint qHash(const TextStyle &textStyle)
+auto qHash(const TextStyle &textStyle)
{
return ::qHash(quint8(textStyle));
}
@@ -202,7 +202,7 @@ QTextCharFormat FontSettings::toTextCharFormat(TextStyle category) const
return tf;
}
-uint qHash(TextStyles textStyles)
+auto qHash(TextStyles textStyles)
{
return ::qHash(reinterpret_cast<quint64&>(textStyles));
}
diff --git a/src/plugins/texteditor/snippets/snippetoverlay.cpp b/src/plugins/texteditor/snippets/snippetoverlay.cpp
index 568470b90e..287d0d7531 100644
--- a/src/plugins/texteditor/snippets/snippetoverlay.cpp
+++ b/src/plugins/texteditor/snippets/snippetoverlay.cpp
@@ -114,10 +114,10 @@ QTextCursor SnippetOverlay::nextSelectionCursor(const QTextCursor &cursor) const
const SnippetSelection &currentSelection = selectionForCursor(cursor);
if (currentSelection.variableIndex >= 0) {
int nextVariableIndex = currentSelection.variableIndex + 1;
- if (nextVariableIndex >= m_variables.size()) {
+ if (!m_variables.contains(nextVariableIndex)) {
if (m_finalSelectionIndex >= 0)
return cursorForIndex(m_finalSelectionIndex);
- nextVariableIndex = 0;
+ nextVariableIndex = m_variables.firstKey();
}
for (int selectionIndex : m_variables[nextVariableIndex]) {
@@ -142,8 +142,8 @@ QTextCursor SnippetOverlay::previousSelectionCursor(const QTextCursor &cursor) c
const SnippetSelection &currentSelection = selectionForCursor(cursor);
if (currentSelection.variableIndex >= 0) {
int previousVariableIndex = currentSelection.variableIndex - 1;
- if (previousVariableIndex < 0)
- previousVariableIndex = m_variables.size() - 1;
+ if (!m_variables.contains(previousVariableIndex))
+ previousVariableIndex = m_variables.lastKey();
const QList<int> &equivalents = m_variables[previousVariableIndex];
for (int i = equivalents.size() - 1; i >= 0; --i) {
diff --git a/src/plugins/texteditor/texteditor.cpp b/src/plugins/texteditor/texteditor.cpp
index d7643af772..90d141808a 100644
--- a/src/plugins/texteditor/texteditor.cpp
+++ b/src/plugins/texteditor/texteditor.cpp
@@ -1966,7 +1966,7 @@ void TextEditorWidget::indent()
void TextEditorWidget::unindent()
{
- setMultiTextCursor(textDocument()->indent(multiTextCursor()));
+ setMultiTextCursor(textDocument()->unindent(multiTextCursor()));
}
void TextEditorWidget::undo()
@@ -8255,7 +8255,7 @@ IEditor *BaseTextEditor::duplicate()
QT_BEGIN_NAMESPACE
-uint qHash(const QColor &color)
+Utils::QHashValueType qHash(const QColor &color)
{
return color.rgba();
}
diff --git a/src/plugins/texteditor/texteditor.h b/src/plugins/texteditor/texteditor.h
index 38cbdd01d3..5811f466e4 100644
--- a/src/plugins/texteditor/texteditor.h
+++ b/src/plugins/texteditor/texteditor.h
@@ -41,6 +41,7 @@
#include <utils/elidinglabel.h>
#include <utils/link.h>
#include <utils/multitextcursor.h>
+#include <utils/porting.h>
#include <utils/uncommentselection.h>
#include <QPlainTextEdit>
@@ -685,6 +686,6 @@ private:
QT_BEGIN_NAMESPACE
-uint qHash(const QColor &color);
+Utils::QHashValueType qHash(const QColor &color);
QT_END_NAMESPACE
diff --git a/src/plugins/vcsbase/vcsbaseeditor.cpp b/src/plugins/vcsbase/vcsbaseeditor.cpp
index d24b96dd5f..c2f4d4a0c9 100644
--- a/src/plugins/vcsbase/vcsbaseeditor.cpp
+++ b/src/plugins/vcsbase/vcsbaseeditor.cpp
@@ -958,18 +958,19 @@ void VcsBaseEditorWidget::slotCursorPositionChanged()
// Adapt entries combo to new position
// if the cursor goes across a file line.
const int newCursorLine = textCursor().blockNumber();
- if (newCursorLine == d->m_cursorLine)
- return;
- // Which section does it belong to?
- d->m_cursorLine = newCursorLine;
- const int section = sectionOfLine(d->m_cursorLine, d->m_entrySections);
- if (section != -1) {
- QComboBox *entriesComboBox = d->entriesComboBox();
- if (entriesComboBox->currentIndex() != section) {
- QSignalBlocker blocker(entriesComboBox);
- entriesComboBox->setCurrentIndex(section);
+ if (newCursorLine != d->m_cursorLine) {
+ // Which section does it belong to?
+ d->m_cursorLine = newCursorLine;
+ const int section = sectionOfLine(d->m_cursorLine, d->m_entrySections);
+ if (section != -1) {
+ QComboBox *entriesComboBox = d->entriesComboBox();
+ if (entriesComboBox->currentIndex() != section) {
+ QSignalBlocker blocker(entriesComboBox);
+ entriesComboBox->setCurrentIndex(section);
+ }
}
}
+ TextEditorWidget::slotCursorPositionChanged();
}
void VcsBaseEditorWidget::contextMenuEvent(QContextMenuEvent *e)
@@ -983,8 +984,10 @@ void VcsBaseEditorWidget::contextMenuEvent(QContextMenuEvent *e)
handler->fillContextMenu(menu, d->m_parameters->type);
}
}
- if (!menu)
- menu = createStandardContextMenu();
+ if (!menu) {
+ menu = new QMenu;
+ appendStandardContextMenuActions(menu);
+ }
switch (d->m_parameters->type) {
case LogOutput: // log might have diff
case DiffOutput: {
diff --git a/src/plugins/webassembly/webassemblyrunconfiguration.cpp b/src/plugins/webassembly/webassemblyrunconfiguration.cpp
index 82d7f8d9a5..123887caf7 100644
--- a/src/plugins/webassembly/webassemblyrunconfiguration.cpp
+++ b/src/plugins/webassembly/webassemblyrunconfiguration.cpp
@@ -40,25 +40,32 @@ using namespace Utils;
namespace WebAssembly {
namespace Internal {
+static FilePath pythonInterpreter(const Environment &env)
+{
+ const QString emsdkPythonEnvVarKey("EMSDK_PYTHON");
+ if (env.hasKey(emsdkPythonEnvVarKey))
+ return FilePath::fromUserInput(env.value(emsdkPythonEnvVarKey));
+
+ // FIXME: Centralize addPythonsFromPath() from the Python plugin and use that
+ for (const char *interpreterCandidate : {"python3", "python", "python2"}) {
+ const FilePath interpereter = env.searchInPath(QLatin1String(interpreterCandidate));
+ if (interpereter.isExecutableFile())
+ return interpereter;
+ }
+ return {};
+}
+
static CommandLine emrunCommand(Target *target, const QString &browser, const QString &port)
{
if (BuildConfiguration *bc = target->activeBuildConfiguration()) {
- const QFileInfo emrun = bc->environment().searchInPath("emrun").toFileInfo();
- auto html = bc->buildDirectory().pathAppended(target->project()->displayName() + ".html");
-
- // On Windows, we need to use the python interpreter (it comes with the emsdk) to ensure
- // that the web server is killed when the application is stopped in Qt Creator.
- // On Non-windows, we prefer using the shell script, because that knows how to find the
- // right python (not part of emsdk). The shell script stays attached to the server process.
- const FilePath interpreter = HostOsInfo::isWindowsHost()
- ? FilePath::fromUserInput(bc->environment().value("EMSDK_PYTHON"))
- : bc->environment().searchInPath("sh");
- const QString emrunLaunchScript = HostOsInfo::isWindowsHost()
- ? emrun.absolutePath() + "/" + emrun.baseName() + ".py"
- : emrun.absoluteFilePath();
-
- return CommandLine(interpreter, {
- emrunLaunchScript,
+ const Environment env = bc->environment();
+ const FilePath emrun = env.searchInPath("emrun");
+ const FilePath emrunPy = emrun.absolutePath().pathAppended(emrun.baseName() + ".py");
+ const FilePath html =
+ bc->buildDirectory().pathAppended(target->project()->displayName() + ".html");
+
+ return CommandLine(pythonInterpreter(env), {
+ emrunPy.path(),
"--browser", browser,
"--port", port,
"--no_emrun_detect",
diff --git a/src/shared/proparser/proitems.cpp b/src/shared/proparser/proitems.cpp
index 1f4a436115..8980e4c216 100644
--- a/src/shared/proparser/proitems.cpp
+++ b/src/shared/proparser/proitems.cpp
@@ -114,7 +114,7 @@ uint ProString::updatedHash() const
return (m_hash = hash(m_string.constData() + m_offset, m_length));
}
-uint qHash(const ProString &str)
+Utils::QHashValueType qHash(const ProString &str)
{
if (!(str.m_hash & 0x80000000))
return str.m_hash;
diff --git a/src/shared/proparser/proitems.h b/src/shared/proparser/proitems.h
index a16e0399d1..4da7e5444b 100644
--- a/src/shared/proparser/proitems.h
+++ b/src/shared/proparser/proitems.h
@@ -182,7 +182,7 @@ private:
int m_file;
mutable uint m_hash;
uint updatedHash() const;
- friend uint qHash(const ProString &str);
+ friend Utils::QHashValueType qHash(const ProString &str);
friend QString operator+(const ProString &one, const ProString &two);
friend class ProKey;
};
@@ -253,7 +253,7 @@ template <> struct QConcatenable<ProKey> : private QAbstractConcatenable
};
-uint qHash(const ProString &str);
+Utils::QHashValueType qHash(const ProString &str);
inline QString &operator+=(QString &that, const ProString &other)
{ return that += other.toStringView(); }
diff --git a/src/shared/proparser/qmakeevaluator.cpp b/src/shared/proparser/qmakeevaluator.cpp
index ff87a1b8f4..b937037b1e 100644
--- a/src/shared/proparser/qmakeevaluator.cpp
+++ b/src/shared/proparser/qmakeevaluator.cpp
@@ -104,7 +104,7 @@ QMakeBaseKey::QMakeBaseKey(const QString &_root, const QString &_stash, bool _ho
{
}
-uint qHash(const QMakeBaseKey &key)
+Utils::QHashValueType qHash(const QMakeBaseKey &key)
{
return qHash(key.root) ^ qHash(key.stash) ^ (uint)key.hostBuild;
}
diff --git a/src/shared/proparser/qmakeglobals.h b/src/shared/proparser/qmakeglobals.h
index 2baeab4bf5..36b1c08c41 100644
--- a/src/shared/proparser/qmakeglobals.h
+++ b/src/shared/proparser/qmakeglobals.h
@@ -27,6 +27,7 @@
#include "qmake_global.h"
#include "proitems.h"
+#include <utils/porting.h>
#ifdef QT_BUILD_QMAKE
# include <property.h>
@@ -58,7 +59,7 @@ public:
bool hostBuild;
};
-uint qHash(const QMakeBaseKey &key);
+Utils::QHashValueType qHash(const QMakeBaseKey &key);
bool operator==(const QMakeBaseKey &one, const QMakeBaseKey &two);
class QMakeBaseEnv
diff --git a/src/shared/qbs b/src/shared/qbs
-Subproject a35ff56175cc8c993b54bb1d92ff71ba4532fc8
+Subproject 966689ab499725cb7e7ab1157043b968a1a39e6
diff --git a/src/tools/qml2puppet/CMakeLists.txt b/src/tools/qml2puppet/CMakeLists.txt
index 924e3a838c..4606ee5708 100644
--- a/src/tools/qml2puppet/CMakeLists.txt
+++ b/src/tools/qml2puppet/CMakeLists.txt
@@ -97,6 +97,7 @@ extend_qtc_library(qml2puppet_static
)
add_qtc_executable(qml2puppet
+ CONDITION TARGET Qt5::QuickPrivate
DEPENDS
Qt5::CorePrivate Qt5::Widgets Qt5::QmlPrivate
Qt5::QuickPrivate Qt5::Network Qt5::GuiPrivate
diff --git a/tests/auto/android/CMakeLists.txt b/tests/auto/android/CMakeLists.txt
index 8f328fe98e..bf132fe599 100644
--- a/tests/auto/android/CMakeLists.txt
+++ b/tests/auto/android/CMakeLists.txt
@@ -1,5 +1,6 @@
add_qtc_test(tst_avdmanageroutputparser
DEPENDS Utils
+ PLUGIN_DEPENDS Android
INCLUDES
"${PROJECT_SOURCE_DIR}/src/plugins"
"${PROJECT_SOURCE_DIR}/src/plugins/android"
@@ -9,6 +10,8 @@ add_qtc_test(tst_avdmanageroutputparser
"${PROJECT_SOURCE_DIR}/src/plugins/android/avdmanageroutputparser.h"
"${PROJECT_SOURCE_DIR}/src/plugins/android/androiddeviceinfo.cpp"
"${PROJECT_SOURCE_DIR}/src/plugins/android/androiddeviceinfo.h"
+ "${PROJECT_SOURCE_DIR}/src/plugins/android/androidmanager.cpp"
+ "${PROJECT_SOURCE_DIR}/src/plugins/android/androidmanager.h"
)
qtc_add_resources(tst_avdmanageroutputparser tst_avdmanageroutputparser_rcc
diff --git a/tests/auto/languageserverprotocol/tst_languageserverprotocol.cpp b/tests/auto/languageserverprotocol/tst_languageserverprotocol.cpp
index db994a3c5b..20fb60cd53 100644
--- a/tests/auto/languageserverprotocol/tst_languageserverprotocol.cpp
+++ b/tests/auto/languageserverprotocol/tst_languageserverprotocol.cpp
@@ -552,7 +552,7 @@ void tst_LanguageServerProtocol::range_data()
auto pos = [](int pos) { return Position(0, pos); };
QTest::newRow("both ranges empty")
- << Range(pos(0), pos(0)) << Range(pos(0), pos(0)) << false << true << true;
+ << Range(pos(0), pos(0)) << Range(pos(0), pos(0)) << true << true << true;
QTest::newRow("equal ranges")
<< Range(pos(0), pos(1)) << Range(pos(0), pos(1)) << true << true << true;
QTest::newRow("r1 before r2")
@@ -562,7 +562,7 @@ void tst_LanguageServerProtocol::range_data()
QTest::newRow("r1 starts before r2 overlapping")
<< Range(pos(0), pos(2)) << Range(pos(1), pos(3)) << true << false << false;
QTest::newRow("empty r1 on r2 start")
- << Range(pos(0), pos(0)) << Range(pos(0), pos(1)) << false << false << true;
+ << Range(pos(0), pos(0)) << Range(pos(0), pos(1)) << true << false << true;
QTest::newRow("r1 inside r2 equal start")
<< Range(pos(0), pos(1)) << Range(pos(0), pos(2)) << true << false << true;
QTest::newRow("r1 inside r2 equal start")
@@ -576,7 +576,7 @@ void tst_LanguageServerProtocol::range_data()
QTest::newRow("r1 ends after r2 overlapping")
<< Range(pos(1), pos(3)) << Range(pos(0), pos(2)) << true << false << false;
QTest::newRow("empty r1 on r2 end")
- << Range(pos(1), pos(1)) << Range(pos(0), pos(1)) << false << false << true;
+ << Range(pos(1), pos(1)) << Range(pos(0), pos(1)) << true << false << true;
QTest::newRow("r1 adjacent after r2")
<< Range(pos(1), pos(2)) << Range(pos(0), pos(1)) << false << false << false;
QTest::newRow("r1 behind r2")
diff --git a/tests/auto/qml/codemodel/check/equality-checks.qml b/tests/auto/qml/codemodel/check/equality-checks.qml
index b562625c23..0a24cccce9 100644
--- a/tests/auto/qml/codemodel/check/equality-checks.qml
+++ b/tests/auto/qml/codemodel/check/equality-checks.qml
@@ -86,7 +86,7 @@ Rectangle {
if (n === s) {} // 325 15 17
if (n === n) {}
if (n === N) {} // 325 15 17
- if (n === u) {} // 325 15 17
+ if (n === u) {}
if (n === b) {} // 325 15 17
if (n === o) {} // 325 15 17
if (n === k) {}
@@ -101,7 +101,7 @@ Rectangle {
if (N === k) {}
if (u === s) {} // 325 15 17
- if (u === n) {} // 325 15 17
+ if (u === n) {}
if (u === N) {}
if (u === u) {}
if (u === b) {} // 325 15 17
@@ -132,5 +132,25 @@ Rectangle {
if (k === b) {}
if (k === o) {}
if (k === k) {}
+
+ var nObj = Number("0")
+ var nNum = Number.fromLocaleString("0")
+ if (n === 1) {}
+ if (nObj === 1) {}
+ if (nNum === 1) {}
+
+ }
+
+ ListView {
+ model: ListModel{ id: myModel }
+ delegate: Item {
+ MouseArea {
+ anchors.fill: parent
+ hoverEnabled: true
+ onClicked: {
+ if (index === -1) {}
+ }
+ }
+ }
}
}
diff --git a/tests/manual/docker/Dockerfile-qt-5-ubuntu-20.04-build b/tests/manual/docker/Dockerfile-qt-5-ubuntu-20.04-build
index be10684ac3..6aa5aad09e 100644
--- a/tests/manual/docker/Dockerfile-qt-5-ubuntu-20.04-build
+++ b/tests/manual/docker/Dockerfile-qt-5-ubuntu-20.04-build
@@ -1,10 +1,10 @@
FROM ubuntu:20.04
-RUN apt update && \
- apt upgrade -y && \
- apt dist-upgrade -y && \
- apt install -y gpg wget software-properties-common
+RUN apt-get update && \
+ apt-get upgrade -y && \
+ apt-get dist-upgrade -y && \
+ apt-get install -y gpg wget software-properties-common
RUN wget -O - https://apt.kitware.com/keys/kitware-archive-latest.asc 2>/dev/null \
| gpg --dearmor - \
@@ -12,13 +12,17 @@ RUN wget -O - https://apt.kitware.com/keys/kitware-archive-latest.asc 2>/dev/nul
RUN apt-add-repository -y 'deb https://apt.kitware.com/ubuntu/ focal main'
-RUN DEBIAN_FRONTEND=noninteractive apt-get install -y \
+RUN apt-get update && \
+ DEBIAN_FRONTEND=noninteractive apt-get install -y \
git \
openssh-client \
sudo \
vim \
cmake \
qtbase5-dev \
+ qtdeclarative5-dev \
+ qtquickcontrols2-5-dev \
+ qtdeclarative5-dev-tools \
libqt5core5a \
libqt5widgets5 \
libqt5quick5 \
@@ -30,5 +34,6 @@ RUN DEBIAN_FRONTEND=noninteractive apt-get install -y \
nim \
linux-tools-common \
valgrind \
- && apt-get clean \
- && rm -rf /var/lib/apt/lists/*
+ && apt-get clean
+
+# && rm -rf /var/lib/apt/lists/*
diff --git a/tests/unit/unittest/CMakeLists.txt b/tests/unit/unittest/CMakeLists.txt
index 6252f4517d..36aa86e631 100644
--- a/tests/unit/unittest/CMakeLists.txt
+++ b/tests/unit/unittest/CMakeLists.txt
@@ -481,8 +481,7 @@ get_filename_component(
ABSOLUTE
)
-
-if (EXISTS ../../../../qmldom_standalone/src/qmldom/standalone)
+if(EXISTS ${QMLDOM_STANDALONE_CMAKELISTS} AND Qt6_FOUND)
add_subdirectory(
../../../../qmldom_standalone/src/qmldom/standalone
${CMAKE_CURRENT_BINARY_DIR}/qmldom_standalone)
@@ -491,9 +490,16 @@ if (EXISTS ../../../../qmldom_standalone/src/qmldom/standalone)
RUNTIME_OUTPUT_DIRECTORY "$<TARGET_PROPERTY:QmlJS,RUNTIME_OUTPUT_DIRECTORY>"
LIBRARY_OUTPUT_DIRECTORY "$<TARGET_PROPERTY:QmlJS,LIBRARY_OUTPUT_DIRECTORY>")
- extend_qtc_test(unittest
- DEPENDS qmldomlib
- SOURCES
- qmldom-test.cpp
+ extend_qtc_test(unittest
+ DEPENDS qmldomlib
+ SOURCES
+ qmldocumentparser-test.cpp
+ qmltypesparser-test.cpp
+ )
+ extend_qtc_test(unittest
+ SOURCES_PREFIX "${QmlDesignerDir}/designercore"
+ SOURCES
+ projectstorage/qmldocumentparser.cpp projectstorage/qmldocumentparser.h
+ projectstorage/qmltypesparser.cpp projectstorage/qmltypesparser.h
)
endif()
diff --git a/tests/unit/unittest/gtest-creator-printing.cpp b/tests/unit/unittest/gtest-creator-printing.cpp
index 89577c1f05..3123ffcf1d 100644
--- a/tests/unit/unittest/gtest-creator-printing.cpp
+++ b/tests/unit/unittest/gtest-creator-printing.cpp
@@ -934,7 +934,7 @@ std::ostream &operator<<(std::ostream &out, const Diagnostic &diag) {
} // namespace ClangTools
namespace QmlDesigner {
-
+namespace {
const char *sourceTypeToText(SourceType sourceType)
{
switch (sourceType) {
@@ -950,6 +950,7 @@ const char *sourceTypeToText(SourceType sourceType)
return "";
}
+} // namespace
std::ostream &operator<<(std::ostream &out, const FileStatus &fileStatus)
{
@@ -1015,8 +1016,8 @@ TypeAccessSemantics cleanFlags(TypeAccessSemantics accessSemantics)
const char *typeAccessSemanticsToString(TypeAccessSemantics accessSemantics)
{
switch (cleanFlags(accessSemantics)) {
- case TypeAccessSemantics::Invalid:
- return "Invalid";
+ case TypeAccessSemantics::None:
+ return "None";
case TypeAccessSemantics::Reference:
return "Reference";
case TypeAccessSemantics::Sequence:
@@ -1055,6 +1056,20 @@ const char *isQualifiedToString(IsQualified isQualified)
return "";
}
+const char *importKindToText(ImportKind kind)
+{
+ switch (kind) {
+ case ImportKind::Module:
+ return "Module";
+ case ImportKind::Directory:
+ return "Directory";
+ case ImportKind::QmlTypesDependency:
+ return "QmlTypesDependency";
+ }
+
+ return "";
+}
+
} // namespace
std::ostream &operator<<(std::ostream &out, TypeAccessSemantics accessSemantics)
@@ -1080,8 +1095,8 @@ std::ostream &operator<<(std::ostream &out, Version version)
std::ostream &operator<<(std::ostream &out, const ExportedType &exportedType)
{
- return out << "(\"" << exportedType.name << "\""
- << ", " << exportedType.version << ")";
+ return out << "(\"" << exportedType.name << "\"," << exportedType.moduleId << ", "
+ << exportedType.version << ")";
}
std::ostream &operator<<(std::ostream &out, const NativeType &nativeType)
@@ -1101,10 +1116,9 @@ std::ostream &operator<<(std::ostream &out, const QualifiedImportedType &importe
std::ostream &operator<<(std::ostream &out, const Type &type)
{
using Utils::operator<<;
- return out << "(moduleId: " << type.moduleId << ", typename: \"" << type.typeName
- << "\", prototype: " << type.prototype << ", " << type.accessSemantics
- << ", source: " << type.sourceId << ", exports: " << type.exportedTypes
- << ", properties: " << type.propertyDeclarations
+ return out << "( typename: \"" << type.typeName << "\", prototype: " << type.prototype << ", "
+ << type.prototypeId << ", " << type.accessSemantics << ", source: " << type.sourceId
+ << ", exports: " << type.exportedTypes << ", properties: " << type.propertyDeclarations
<< ", functions: " << type.functionDeclarations
<< ", signals: " << type.signalDeclarations << ")";
}
@@ -1112,9 +1126,10 @@ std::ostream &operator<<(std::ostream &out, const Type &type)
std::ostream &operator<<(std::ostream &out, const PropertyDeclaration &propertyDeclaration)
{
using Utils::operator<<;
- return out << "(\"" << propertyDeclaration.name << "\", \"" << propertyDeclaration.typeName
- << "\", " << propertyDeclaration.traits << ", " << propertyDeclaration.typeId
- << ", \"" << propertyDeclaration.aliasPropertyName << "\")";
+ return out << "(\"" << propertyDeclaration.name << "\", " << propertyDeclaration.typeName
+ << ", " << propertyDeclaration.typeId << ", " << propertyDeclaration.traits << ", "
+ << propertyDeclaration.typeId << ", \"" << propertyDeclaration.aliasPropertyName
+ << "\")";
}
std::ostream &operator<<(std::ostream &out, PropertyDeclarationTraits traits)
@@ -1171,14 +1186,14 @@ std::ostream &operator<<(std::ostream &out, const EnumerationDeclaration &enumer
<< enumerationDeclaration.enumeratorDeclarations << ")";
}
-std::ostream &operator<<(std::ostream &out, const Module &module)
+std::ostream &operator<<(std::ostream &out, const ImportKind &importKind)
{
- return out << "(" << module.name << ", " << module.sourceId << ")";
+ return out << importKindToText(importKind);
}
std::ostream &operator<<(std::ostream &out, const Import &import)
{
- return out << "(" << import.name << ", " << import.version << ", " << import.sourceId << ")";
+ return out << "(" << import.moduleId << ", " << import.version << ", " << import.sourceId << ")";
}
} // namespace Storage
diff --git a/tests/unit/unittest/gtest-creator-printing.h b/tests/unit/unittest/gtest-creator-printing.h
index d2c20d92b5..074fada6d9 100644
--- a/tests/unit/unittest/gtest-creator-printing.h
+++ b/tests/unit/unittest/gtest-creator-printing.h
@@ -260,8 +260,7 @@ class ParameterDeclaration;
class SignalDeclaration;
class EnumerationDeclaration;
class EnumeratorDeclaration;
-class Module;
-class ModuleDependency;
+enum class ImportKind : char;
class Import;
enum class IsQualified : int;
@@ -280,8 +279,7 @@ std::ostream &operator<<(std::ostream &out, const ParameterDeclaration &paramete
std::ostream &operator<<(std::ostream &out, const SignalDeclaration &signalDeclaration);
std::ostream &operator<<(std::ostream &out, const EnumerationDeclaration &enumerationDeclaration);
std::ostream &operator<<(std::ostream &out, const EnumeratorDeclaration &enumeratorDeclaration);
-std::ostream &operator<<(std::ostream &out, const Module &module);
-std::ostream &operator<<(std::ostream &out, const ModuleDependency &module);
+std::ostream &operator<<(std::ostream &out, const ImportKind &importKind);
std::ostream &operator<<(std::ostream &out, const Import &import);
std::ostream &operator<<(std::ostream &out, IsQualified isQualified);
diff --git a/tests/unit/unittest/projectstorage-test.cpp b/tests/unit/unittest/projectstorage-test.cpp
index da71b36d31..43ac728fd9 100644
--- a/tests/unit/unittest/projectstorage-test.cpp
+++ b/tests/unit/unittest/projectstorage-test.cpp
@@ -46,6 +46,7 @@ using QmlDesigner::SourceIds;
using QmlDesigner::TypeId;
using QmlDesigner::Cache::Source;
using QmlDesigner::Cache::SourceContext;
+using QmlDesigner::Storage::SynchronizationPackage;
using QmlDesigner::Storage::TypeAccessSemantics;
namespace Storage = QmlDesigner::Storage;
@@ -83,34 +84,18 @@ MATCHER_P2(IsSourceNameAndSourceContextId,
&& sourceNameAndSourceContextId.sourceContextId == id;
}
-MATCHER_P5(IsStorageType,
- moduleId,
- typeName,
- prototype,
- accessSemantics,
+MATCHER_P4(IsStorageType,
sourceId,
- std::string(negation ? "isn't " : "is ")
- + PrintToString(Storage::Type{moduleId, typeName, prototype, accessSemantics, sourceId}))
-{
- const Storage::Type &type = arg;
-
- return type.moduleId == moduleId && type.typeName == typeName
- && type.accessSemantics == accessSemantics && type.sourceId == sourceId
- && Storage::ImportedTypeName{prototype} == type.prototype;
-}
-
-MATCHER_P4(IsStorageTypeWithInvalidSourceId,
- moduleId,
typeName,
- prototype,
+ prototypeId,
accessSemantics,
std::string(negation ? "isn't " : "is ")
- + PrintToString(Storage::Type{moduleId, typeName, prototype, accessSemantics, SourceId{}}))
+ + PrintToString(Storage::Type{typeName, prototypeId, accessSemantics, sourceId}))
{
const Storage::Type &type = arg;
- return type.moduleId == moduleId && type.typeName == typeName && type.prototype == prototype
- && type.accessSemantics == accessSemantics && !type.sourceId.isValid();
+ return type.sourceId == sourceId && type.typeName == typeName
+ && type.accessSemantics == accessSemantics && prototypeId.id == type.prototypeId.id;
}
MATCHER_P(IsExportedType,
@@ -122,6 +107,17 @@ MATCHER_P(IsExportedType,
return type.name == name;
}
+MATCHER_P2(IsExportedType,
+ moduleId,
+ name,
+ std::string(negation ? "isn't " : "is ")
+ + PrintToString(Storage::ExportedType{moduleId, name}))
+{
+ const Storage::ExportedType &type = arg;
+
+ return type.moduleId == moduleId && type.name == name;
+}
+
MATCHER_P3(IsExportedType,
name,
majorVersion,
@@ -135,56 +131,51 @@ MATCHER_P3(IsExportedType,
return type.name == name && type.version == Storage::Version{majorVersion, minorVersion};
}
+MATCHER_P4(IsExportedType,
+ moduleId,
+ name,
+ majorVersion,
+ minorVersion,
+ std::string(negation ? "isn't " : "is ")
+ + PrintToString(Storage::ExportedType{moduleId,
+ name,
+ Storage::Version{majorVersion, minorVersion}}))
+{
+ const Storage::ExportedType &type = arg;
+
+ return type.moduleId == moduleId && type.name == name
+ && type.version == Storage::Version{majorVersion, minorVersion};
+}
+
MATCHER_P3(IsPropertyDeclaration,
name,
- typeName,
+ propertyTypeId,
traits,
std::string(negation ? "isn't " : "is ")
- + PrintToString(Storage::PropertyDeclaration{name, typeName, traits}))
+ + PrintToString(Storage::PropertyDeclaration{name, propertyTypeId, traits}))
{
const Storage::PropertyDeclaration &propertyDeclaration = arg;
- return propertyDeclaration.name == name
- && Storage::ImportedTypeName{typeName} == propertyDeclaration.typeName
+ return propertyDeclaration.name == name && propertyTypeId == propertyDeclaration.propertyTypeId
&& propertyDeclaration.traits == traits;
}
MATCHER_P4(IsPropertyDeclaration,
name,
- typeName,
+ propertyTypeId,
traits,
aliasPropertyName,
std::string(negation ? "isn't " : "is ")
- + PrintToString(Storage::PropertyDeclaration(name, typeName, traits, aliasPropertyName)))
+ + PrintToString(
+ Storage::PropertyDeclaration{name, propertyTypeId, traits, aliasPropertyName}))
{
const Storage::PropertyDeclaration &propertyDeclaration = arg;
- return propertyDeclaration.name == name
- && Utils::visit([&](auto &&v) -> bool { return v.name == typeName.name; },
- propertyDeclaration.typeName)
+ return propertyDeclaration.name == name && propertyTypeId == propertyDeclaration.propertyTypeId
&& propertyDeclaration.aliasPropertyName == aliasPropertyName
&& propertyDeclaration.traits == traits;
}
-MATCHER_P(IsModule,
- name,
- std::string(negation ? "isn't " : "is ") + PrintToString(Storage::Module{name}))
-{
- const Storage::Module &module = arg;
-
- return module.name == name;
-}
-
-MATCHER_P2(IsModule,
- name,
- sourceId,
- std::string(negation ? "isn't " : "is ") + PrintToString(Storage::Module{name, sourceId}))
-{
- const Storage::Module &module = arg;
-
- return module.name == name;
-}
-
class ProjectStorage : public testing::Test
{
protected:
@@ -212,214 +203,209 @@ protected:
storage.fetchSourceId(sourceContextId3, "bar");
}
- auto createTypes()
+ auto createSimpleSynchronizationPackage()
{
- imports.emplace_back("Qml", Storage::Version{}, sourceId1);
- imports.emplace_back("Qml", Storage::Version{}, sourceId2);
- imports.emplace_back("QtQuick", Storage::Version{}, sourceId1);
-
- importsSourceId1.emplace_back("Qml", Storage::Version{}, sourceId1);
- importsSourceId1.emplace_back("QtQuick", Storage::Version{}, sourceId1);
-
- importsSourceId2.emplace_back("Qml", Storage::Version{}, sourceId2);
-
- return Storage::Types{
- Storage::Type{
- qtQuickModuleId,
- "QQuickItem",
- Storage::NativeType{"QObject"},
- TypeAccessSemantics::Reference,
- sourceId1,
- {Storage::ExportedType{"Item"}},
- {Storage::PropertyDeclaration{"data",
- Storage::NativeType{"QObject"},
- Storage::PropertyDeclarationTraits::IsList},
- Storage::PropertyDeclaration{"children",
- Storage::ImportedType{"Item"},
- Storage::PropertyDeclarationTraits::IsList
- | Storage::PropertyDeclarationTraits::IsReadOnly}},
- {Storage::FunctionDeclaration{"execute", "", {Storage::ParameterDeclaration{"arg", ""}}},
- Storage::FunctionDeclaration{
- "values",
- "Vector3D",
- {Storage::ParameterDeclaration{"arg1", "int"},
- Storage::ParameterDeclaration{"arg2",
- "QObject",
- Storage::PropertyDeclarationTraits::IsPointer},
- Storage::ParameterDeclaration{"arg3", "string"}}}},
- {Storage::SignalDeclaration{"execute", {Storage::ParameterDeclaration{"arg", ""}}},
- Storage::SignalDeclaration{
- "value0s",
- {Storage::ParameterDeclaration{"arg1", "int"},
- Storage::ParameterDeclaration{"arg2",
- "QObject",
- Storage::PropertyDeclarationTraits::IsPointer},
- Storage::ParameterDeclaration{"arg3", "string"}}}},
- {Storage::EnumerationDeclaration{"Enum",
- {Storage::EnumeratorDeclaration{"Foo"},
- Storage::EnumeratorDeclaration{"Bar", 32}}},
- Storage::EnumerationDeclaration{"Type",
- {Storage::EnumeratorDeclaration{"Foo"},
- Storage::EnumeratorDeclaration{"Poo", 12}}}}},
- Storage::Type{qmlModuleId,
- "QObject",
- Storage::NativeType{},
+ SynchronizationPackage package;
+
+ package.imports.emplace_back(qmlModuleId, Storage::Version{}, sourceId1);
+ package.imports.emplace_back(qmlNativeModuleId, Storage::Version{}, sourceId1);
+ package.imports.emplace_back(qtQuickModuleId, Storage::Version{}, sourceId1);
+ package.imports.emplace_back(qtQuickNativeModuleId, Storage::Version{}, sourceId1);
+ package.imports.emplace_back(qmlModuleId, Storage::Version{}, sourceId2);
+ package.imports.emplace_back(qmlNativeModuleId, Storage::Version{}, sourceId2);
+
+ importsSourceId1.emplace_back(qmlModuleId, Storage::Version{}, sourceId1);
+ importsSourceId1.emplace_back(qmlNativeModuleId, Storage::Version{}, sourceId1);
+ importsSourceId1.emplace_back(qtQuickModuleId, Storage::Version{}, sourceId1);
+ importsSourceId1.emplace_back(qtQuickNativeModuleId, Storage::Version{}, sourceId1);
+
+ importsSourceId2.emplace_back(qmlModuleId, Storage::Version{}, sourceId2);
+ importsSourceId2.emplace_back(qmlNativeModuleId, Storage::Version{}, sourceId2);
+
+ package.types.push_back(Storage::Type{
+ "QQuickItem",
+ Storage::ImportedType{"QObject"},
+ TypeAccessSemantics::Reference,
+ sourceId1,
+ {Storage::ExportedType{qtQuickModuleId, "Item"},
+ Storage::ExportedType{qtQuickNativeModuleId, "QQuickItem"}},
+ {Storage::PropertyDeclaration{"data",
+ Storage::ImportedType{"QObject"},
+ Storage::PropertyDeclarationTraits::IsList},
+ Storage::PropertyDeclaration{"children",
+ Storage::ImportedType{"Item"},
+ Storage::PropertyDeclarationTraits::IsList
+ | Storage::PropertyDeclarationTraits::IsReadOnly}},
+ {Storage::FunctionDeclaration{"execute", "", {Storage::ParameterDeclaration{"arg", ""}}},
+ Storage::FunctionDeclaration{
+ "values",
+ "Vector3D",
+ {Storage::ParameterDeclaration{"arg1", "int"},
+ Storage::ParameterDeclaration{"arg2",
+ "QObject",
+ Storage::PropertyDeclarationTraits::IsPointer},
+ Storage::ParameterDeclaration{"arg3", "string"}}}},
+ {Storage::SignalDeclaration{"execute", {Storage::ParameterDeclaration{"arg", ""}}},
+ Storage::SignalDeclaration{"value0s",
+ {Storage::ParameterDeclaration{"arg1", "int"},
+ Storage::ParameterDeclaration{
+ "arg2", "QObject", Storage::PropertyDeclarationTraits::IsPointer},
+ Storage::ParameterDeclaration{"arg3", "string"}}}},
+ {Storage::EnumerationDeclaration{"Enum",
+ {Storage::EnumeratorDeclaration{"Foo"},
+ Storage::EnumeratorDeclaration{"Bar", 32}}},
+ Storage::EnumerationDeclaration{"Type",
+ {Storage::EnumeratorDeclaration{"Foo"},
+ Storage::EnumeratorDeclaration{"Poo", 12}}}}});
+ package.types.push_back(
+ Storage::Type{"QObject",
+ Storage::ImportedType{},
TypeAccessSemantics::Reference,
sourceId2,
- {Storage::ExportedType{"Object", Storage::Version{2}},
- Storage::ExportedType{"Obj", Storage::Version{2}}}}};
- }
+ {Storage::ExportedType{qmlModuleId, "Object", Storage::Version{2}},
+ Storage::ExportedType{qmlModuleId, "Obj", Storage::Version{2}},
+ Storage::ExportedType{qmlNativeModuleId, "QObject"}}});
- auto createVersionedTypes()
- {
- return Storage::Types{Storage::Type{qmlModuleId,
- "QObject",
- Storage::NativeType{},
- TypeAccessSemantics::Reference,
- sourceId1,
- {Storage::ExportedType{"Object", Storage::Version{1}},
- Storage::ExportedType{"Obj", Storage::Version{1, 2}},
- Storage::ExportedType{"BuiltInObj", Storage::Version{}}}},
- Storage::Type{qmlModuleId,
- "QObject2",
- Storage::NativeType{},
- TypeAccessSemantics::Reference,
- sourceId1,
- {Storage::ExportedType{"Object", Storage::Version{2, 0}},
- Storage::ExportedType{"Obj", Storage::Version{2, 3}}}},
- Storage::Type{qmlModuleId,
- "QObject3",
- Storage::NativeType{},
- TypeAccessSemantics::Reference,
- sourceId1,
- {Storage::ExportedType{"Object", Storage::Version{2, 11}},
- Storage::ExportedType{"Obj", Storage::Version{2, 11}}}},
- Storage::Type{qmlModuleId,
- "QObject4",
- Storage::NativeType{},
- TypeAccessSemantics::Reference,
- sourceId1,
- {Storage::ExportedType{"Object", Storage::Version{3, 4}},
- Storage::ExportedType{"Obj", Storage::Version{3, 4}},
- Storage::ExportedType{"BuiltInObj",
- Storage::Version{3, 4}}}}};
- }
-
- auto createTypesWithExportedTypeNamesOnly()
- {
- auto types = createTypes();
+ package.sourceIds = {sourceId1, sourceId2};
- types[0].prototype = Storage::ImportedType{"Object"};
- types[0].propertyDeclarations[0].typeName = Storage::ImportedType{"Object"};
-
- return types;
+ return package;
}
- auto createTypesWithAliases()
+ auto createSynchronizationPackageWithAliases()
{
- auto types = createTypes();
+ auto package{createSimpleSynchronizationPackage()};
- imports.emplace_back("Qml", Storage::Version{}, sourceId3);
- imports.emplace_back("QtQuick", Storage::Version{}, sourceId3);
+ package.imports.emplace_back(qmlModuleId, Storage::Version{}, sourceId3);
+ package.imports.emplace_back(qmlNativeModuleId, Storage::Version{}, sourceId3);
+ package.imports.emplace_back(qtQuickModuleId, Storage::Version{}, sourceId3);
+ package.imports.emplace_back(qtQuickNativeModuleId, Storage::Version{}, sourceId3);
- imports.emplace_back("Qml", Storage::Version{}, sourceId4);
- imports.emplace_back("/path/to", Storage::Version{}, sourceId4);
+ package.imports.emplace_back(qmlModuleId, Storage::Version{}, sourceId4);
+ package.imports.emplace_back(qmlNativeModuleId, Storage::Version{}, sourceId4);
+ package.imports.emplace_back(pathToModuleId, Storage::Version{}, sourceId4);
- importsSourceId3.emplace_back("Qml", Storage::Version{}, sourceId3);
- importsSourceId3.emplace_back("QtQuick", Storage::Version{}, sourceId3);
+ importsSourceId3.emplace_back(qmlModuleId, Storage::Version{}, sourceId3);
+ importsSourceId3.emplace_back(qmlNativeModuleId, Storage::Version{}, sourceId3);
+ importsSourceId3.emplace_back(qtQuickModuleId, Storage::Version{}, sourceId3);
+ importsSourceId3.emplace_back(qtQuickNativeModuleId, Storage::Version{}, sourceId3);
- importsSourceId4.emplace_back("Qml", Storage::Version{}, sourceId4);
- importsSourceId4.emplace_back("/path/to", Storage::Version{}, sourceId4);
+ importsSourceId4.emplace_back(qmlModuleId, Storage::Version{}, sourceId4);
+ importsSourceId4.emplace_back(qmlNativeModuleId, Storage::Version{}, sourceId4);
+ importsSourceId4.emplace_back(pathToModuleId, Storage::Version{}, sourceId4);
- types[1].propertyDeclarations.push_back(
+ package.types[1].propertyDeclarations.push_back(
Storage::PropertyDeclaration{"objects",
- Storage::NativeType{"QObject"},
+ Storage::ImportedType{"QObject"},
Storage::PropertyDeclarationTraits::IsList});
-
- types.push_back(Storage::Type{qtQuickModuleId,
- "QAliasItem",
- Storage::ImportedType{"Item"},
- TypeAccessSemantics::Reference,
- sourceId3,
- {Storage::ExportedType{"AliasItem"}}});
- types.back().propertyDeclarations.push_back(
+ package.types.push_back(
+ Storage::Type{"QAliasItem",
+ Storage::ImportedType{"Item"},
+ TypeAccessSemantics::Reference,
+ sourceId3,
+ {Storage::ExportedType{qtQuickModuleId, "AliasItem"},
+ Storage::ExportedType{qtQuickNativeModuleId, "QAliasItem"}}});
+ package.types.back().propertyDeclarations.push_back(
Storage::PropertyDeclaration{"data",
- Storage::NativeType{"QObject"},
+ Storage::ImportedType{"QObject"},
Storage::PropertyDeclarationTraits::IsList});
- types.back().propertyDeclarations.push_back(
+ package.types.back().propertyDeclarations.push_back(
Storage::PropertyDeclaration{"items", Storage::ImportedType{"Item"}, "children"});
- types.back().propertyDeclarations.push_back(
+ package.types.back().propertyDeclarations.push_back(
Storage::PropertyDeclaration{"objects", Storage::ImportedType{"Item"}, "objects"});
- types.push_back(
- Storage::Type{pathToModuleId,
- "QObject2",
- Storage::NativeType{},
- TypeAccessSemantics::Reference,
- sourceId4,
- {Storage::ExportedType{"Object2"}, Storage::ExportedType{"Obj2"}}});
- types[3].propertyDeclarations.push_back(
+ package.types.push_back(Storage::Type{"QObject2",
+ Storage::ImportedType{},
+ TypeAccessSemantics::Reference,
+ sourceId4,
+ {Storage::ExportedType{pathToModuleId, "Object2"},
+ Storage::ExportedType{pathToModuleId, "Obj2"}}});
+ package.types[3].propertyDeclarations.push_back(
Storage::PropertyDeclaration{"objects",
- Storage::NativeType{"QObject"},
+ Storage::ImportedType{"QObject"},
Storage::PropertyDeclarationTraits::IsList});
- return types;
+ package.sourceIds.push_back(sourceId3);
+ package.sourceIds.push_back(sourceId4);
+
+ return package;
}
- auto createTypesWithRecursiveAliases()
+ auto createSynchronizationPackageWithAliases2()
{
- imports.emplace_back("Qml", Storage::Version{}, sourceId5);
- imports.emplace_back("QtQuick", Storage::Version{}, sourceId5);
-
- auto types = createTypesWithAliases();
- types.push_back(Storage::Type{qtQuickModuleId,
- "QAliasItem2",
- Storage::ImportedType{"Object"},
- TypeAccessSemantics::Reference,
- sourceId5,
- {Storage::ExportedType{"AliasItem2"}}});
-
- types.back().propertyDeclarations.push_back(
- Storage::PropertyDeclaration{"objects", Storage::ImportedType{"AliasItem"}, "objects"});
+ auto package{createSynchronizationPackageWithAliases()};
- return types;
+ package.types[2].prototype = Storage::ImportedType{"Object"};
+ package.types[2].propertyDeclarations.erase(
+ std::next(package.types[2].propertyDeclarations.begin()));
+
+ return package;
}
- auto createTypesWithAliases2()
+ auto createSynchronizationPackageWithRecursiveAliases()
{
- auto types = createTypesWithAliases();
- types[2].prototype = Storage::NativeType{"QObject"};
- types[2].propertyDeclarations.erase(std::next(types[2].propertyDeclarations.begin()));
+ auto package{createSynchronizationPackageWithAliases()};
- return types;
- }
+ package.imports.emplace_back(qmlModuleId, Storage::Version{}, sourceId5);
+ package.imports.emplace_back(qtQuickModuleId, Storage::Version{}, sourceId5);
- Storage::Modules createModules()
- {
- return Storage::Modules{Storage::Module{"Qml", qmlModuleSourceId},
- Storage::Module{"QtQuick", qtQuickModuleSourceId},
- Storage::Module{"/path/to", pathToModuleSourceId}};
- }
+ package.types.push_back(
+ Storage::Type{"QAliasItem2",
+ Storage::ImportedType{"Object"},
+ TypeAccessSemantics::Reference,
+ sourceId5,
+ {Storage::ExportedType{qtQuickModuleId, "AliasItem2"},
+ Storage::ExportedType{qtQuickNativeModuleId, "QAliasItem2"}}});
- Storage::Imports createImports(SourceId sourceId)
- {
- return Storage::Imports{Storage::Import{"Qml", Storage::Version{2}, sourceId},
- Storage::Import{"QtQuick", Storage::Version{}, sourceId},
- Storage::Import{"/path/to", Storage::Version{}, sourceId}};
+ package.types.back().propertyDeclarations.push_back(
+ Storage::PropertyDeclaration{"objects", Storage::ImportedType{"AliasItem"}, "objects"});
+
+ package.sourceIds.push_back(sourceId5);
+
+ return package;
}
- static Storage::Imports createImports(const SourceIds &sourceIds)
+ auto createSynchronizationPackageWithVersions()
{
- Storage::Imports imports;
- imports.reserve(3 * sourceIds.size());
+ SynchronizationPackage package;
+
+ package.types.push_back(
+ Storage::Type{"QObject",
+ Storage::ImportedType{},
+ TypeAccessSemantics::Reference,
+ sourceId1,
+ {Storage::ExportedType{qmlModuleId, "Object", Storage::Version{1}},
+ Storage::ExportedType{qmlModuleId, "Obj", Storage::Version{1, 2}},
+ Storage::ExportedType{qmlModuleId, "BuiltInObj"},
+ Storage::ExportedType{qmlNativeModuleId, "QObject"}}});
+ package.types.push_back(
+ Storage::Type{"QObject2",
+ Storage::ImportedType{},
+ TypeAccessSemantics::Reference,
+ sourceId1,
+ {Storage::ExportedType{qmlModuleId, "Object", Storage::Version{2, 0}},
+ Storage::ExportedType{qmlModuleId, "Obj", Storage::Version{2, 3}},
+ Storage::ExportedType{qmlNativeModuleId, "QObject2"}}});
+ package.types.push_back(
+ Storage::Type{"QObject3",
+ Storage::ImportedType{},
+ TypeAccessSemantics::Reference,
+ sourceId1,
+ {Storage::ExportedType{qmlModuleId, "Object", Storage::Version{2, 11}},
+ Storage::ExportedType{qmlModuleId, "Obj", Storage::Version{2, 11}},
+ Storage::ExportedType{qmlNativeModuleId, "QObject3"}}});
+ package.types.push_back(
+ Storage::Type{"QObject4",
+ Storage::ImportedType{},
+ TypeAccessSemantics::Reference,
+ sourceId1,
+ {Storage::ExportedType{qmlModuleId, "Object", Storage::Version{3, 4}},
+ Storage::ExportedType{qmlModuleId, "Obj", Storage::Version{3, 4}},
+ Storage::ExportedType{qmlModuleId, "BuiltInObj", Storage::Version{3, 4}},
+ Storage::ExportedType{qmlNativeModuleId, "QObject4"}}});
- for (SourceId sourceId : sourceIds) {
- imports.emplace_back("Qml", Storage::Version{2}, sourceId);
- imports.emplace_back("QtQuick", Storage::Version{}, sourceId);
- imports.emplace_back("/path/to", Storage::Version{}, sourceId);
- }
+ package.sourceIds.push_back(sourceId1);
- return imports;
+ return package;
}
template<typename Range>
@@ -428,9 +414,14 @@ protected:
return FileStatuses(range.begin(), range.end());
}
+ TypeId fetchTypeId(SourceId sourceId, Utils::SmallStringView name)
+ {
+ return storage.fetchTypeIdByName(sourceId, name);
+ }
+
protected:
Sqlite::Database database{":memory:", Sqlite::JournalMode::Memory};
- //Sqlite::Database database{TESTDATA_DIR "/aaaa.db", Sqlite::JournalMode::Wal};
+ //Sqlite::Database database{TESTDATA_DIR "/aaaaa.db", Sqlite::JournalMode::Wal};
QmlDesigner::ProjectStorage<Sqlite::Database> storage{database, database.isInitialized()};
QmlDesigner::SourcePathCache<QmlDesigner::ProjectStorage<Sqlite::Database>> sourcePathCache{
storage};
@@ -439,27 +430,16 @@ protected:
QmlDesigner::SourcePathView path3{"/path3/to"};
QmlDesigner::SourcePathView path4{"/path4/to"};
QmlDesigner::SourcePathView path5{"/path5/to"};
- QmlDesigner::SourcePathView modulePath1{"/module/path1/to"};
- QmlDesigner::SourcePathView modulePath2{"/module/path2/to"};
- QmlDesigner::SourcePathView modulePath3{"/module/aaaa/to"};
- QmlDesigner::SourcePathView modulePath4{"/module/ooo/to"};
- QmlDesigner::SourcePathView modulePath5{"/module/xxx/to"};
SourceId sourceId1{sourcePathCache.sourceId(path1)};
SourceId sourceId2{sourcePathCache.sourceId(path2)};
SourceId sourceId3{sourcePathCache.sourceId(path3)};
SourceId sourceId4{sourcePathCache.sourceId(path4)};
SourceId sourceId5{sourcePathCache.sourceId(path5)};
- SourceIds sourceIds{sourceId1, sourceId2, sourceId3, sourceId4, sourceId5};
- SourceId qmlModuleSourceId{sourcePathCache.sourceId(modulePath1)};
- SourceId qtQuickModuleSourceId{sourcePathCache.sourceId(modulePath2)};
- SourceId pathToModuleSourceId{sourcePathCache.sourceId(modulePath3)};
- SourceId moduleSourceId4{sourcePathCache.sourceId(modulePath4)};
- SourceId moduleSourceId5{sourcePathCache.sourceId(modulePath5)};
- Storage::Modules modules{createModules()};
- ModuleId qmlModuleId{&qmlModuleSourceId};
- ModuleId qtQuickModuleId{&qtQuickModuleSourceId};
- ModuleId pathToModuleId{&pathToModuleSourceId};
- Storage::Imports imports;
+ ModuleId qmlModuleId{storage.moduleId("Qml")};
+ ModuleId qmlNativeModuleId{storage.moduleId("Qml-cppnative")};
+ ModuleId qtQuickModuleId{storage.moduleId("QtQuick")};
+ ModuleId qtQuickNativeModuleId{storage.moduleId("QtQuick-cppnative")};
+ ModuleId pathToModuleId{storage.moduleId("/path/to")};
Storage::Imports importsSourceId1;
Storage::Imports importsSourceId2;
Storage::Imports importsSourceId3;
@@ -671,1779 +651,1206 @@ TEST_F(ProjectStorage, FetchSourceIdUnguardedWithNonExistingSourceContextIdThrow
TEST_F(ProjectStorage, SynchronizeTypesAddsNewTypes)
{
- Storage::Types types{createTypes()};
+ auto package{createSimpleSynchronizationPackage()};
- storage.synchronize(
- modules,
- imports,
- types,
- {sourceId1, sourceId2, qmlModuleSourceId, qtQuickModuleSourceId, pathToModuleSourceId},
- {});
+ storage.synchronize(std::move(package));
- ASSERT_THAT(storage.fetchTypes(),
- UnorderedElementsAre(AllOf(IsStorageType(qmlModuleId,
- "QObject",
- Storage::NativeType{},
- TypeAccessSemantics::Reference,
- sourceId2),
- Field(&Storage::Type::exportedTypes,
- UnorderedElementsAre(IsExportedType("Object"),
- IsExportedType("Obj")))),
- AllOf(IsStorageType(qtQuickModuleId,
- "QQuickItem",
- Storage::NativeType{"QObject"},
- TypeAccessSemantics::Reference,
- sourceId1),
- Field(&Storage::Type::exportedTypes,
- UnorderedElementsAre(IsExportedType("Item"))))));
+ ASSERT_THAT(
+ storage.fetchTypes(),
+ UnorderedElementsAre(
+ AllOf(IsStorageType(sourceId2, "QObject", TypeId{}, TypeAccessSemantics::Reference),
+ Field(&Storage::Type::exportedTypes,
+ UnorderedElementsAre(IsExportedType(qmlModuleId, "Object"),
+ IsExportedType(qmlModuleId, "Obj"),
+ IsExportedType(qmlNativeModuleId, "QObject")))),
+ AllOf(IsStorageType(sourceId1,
+ "QQuickItem",
+ fetchTypeId(sourceId2, "QObject"),
+ TypeAccessSemantics::Reference),
+ Field(&Storage::Type::exportedTypes,
+ UnorderedElementsAre(IsExportedType(qtQuickModuleId, "Item"),
+ IsExportedType(qtQuickNativeModuleId, "QQuickItem"))))));
}
TEST_F(ProjectStorage, SynchronizeTypesAddsNewTypesWithExportedPrototypeName)
{
- Storage::Types types{createTypes()};
- types[0].prototype = Storage::ImportedType{"Object"};
+ auto package{createSimpleSynchronizationPackage()};
+ package.types[0].prototype = Storage::ImportedType{"Object"};
- storage.synchronize(
- modules,
- importsSourceId1,
- types,
- {sourceId1, sourceId2, qmlModuleSourceId, qtQuickModuleSourceId, pathToModuleSourceId},
- {});
+ storage.synchronize(std::move(package));
- ASSERT_THAT(storage.fetchTypes(),
- UnorderedElementsAre(AllOf(IsStorageType(qmlModuleId,
- "QObject",
- Storage::NativeType{},
- TypeAccessSemantics::Reference,
- sourceId2),
- Field(&Storage::Type::exportedTypes,
- UnorderedElementsAre(IsExportedType("Object"),
- IsExportedType("Obj")))),
- AllOf(IsStorageType(qtQuickModuleId,
- "QQuickItem",
- Storage::NativeType{"QObject"},
- TypeAccessSemantics::Reference,
- sourceId1),
- Field(&Storage::Type::exportedTypes,
- UnorderedElementsAre(IsExportedType("Item"))))));
+ ASSERT_THAT(
+ storage.fetchTypes(),
+ UnorderedElementsAre(
+ AllOf(IsStorageType(sourceId2, "QObject", TypeId{}, TypeAccessSemantics::Reference),
+ Field(&Storage::Type::exportedTypes,
+ UnorderedElementsAre(IsExportedType(qmlModuleId, "Object"),
+ IsExportedType(qmlModuleId, "Obj"),
+ IsExportedType(qmlNativeModuleId, "QObject")))),
+ AllOf(IsStorageType(sourceId1,
+ "QQuickItem",
+ fetchTypeId(sourceId2, "QObject"),
+ TypeAccessSemantics::Reference),
+ Field(&Storage::Type::exportedTypes,
+ UnorderedElementsAre(IsExportedType(qtQuickModuleId, "Item"),
+ IsExportedType(qtQuickNativeModuleId, "QQuickItem"))))));
}
TEST_F(ProjectStorage, SynchronizeTypesAddsNewTypesThrowsWithWrongPrototypeName)
{
- Storage::Types types{createTypes()};
- types[0].prototype = Storage::ImportedType{"Objec"};
-
- ASSERT_THROW(storage.synchronize(modules,
- imports,
- types,
- {sourceId1,
- sourceId2,
- qmlModuleSourceId,
- qtQuickModuleSourceId,
- pathToModuleSourceId},
- {}),
- QmlDesigner::TypeNameDoesNotExists);
-}
+ auto package{createSimpleSynchronizationPackage()};
+ package.types[0].prototype = Storage::ImportedType{"Objec"};
-TEST_F(ProjectStorage, SynchronizeTypesAddsNewTypesWithMissingModuleAndPrototypeName)
-{
- Storage::Types types{createTypes()};
- types.push_back(Storage::Type{pathToModuleId,
- "QObject2",
- Storage::NativeType{},
- TypeAccessSemantics::Reference,
- sourceId3,
- {Storage::ExportedType{"Object2"}, Storage::ExportedType{"Obj2"}}});
- storage.synchronize(
- modules,
- imports,
- {},
- {sourceId1, sourceId2, sourceId3, qmlModuleSourceId, qtQuickModuleSourceId, pathToModuleSourceId},
- {});
- types[1].prototype = Storage::ImportedType{"Object2"};
-
- ASSERT_THROW(storage.synchronize({}, importsSourceId2, {types[1]}, {sourceId2}, {}),
- QmlDesigner::TypeNameDoesNotExists);
+ ASSERT_THROW(storage.synchronize(std::move(package)), QmlDesigner::TypeNameDoesNotExists);
}
TEST_F(ProjectStorage, SynchronizeTypesAddsNewTypesWithMissingModule)
{
- Storage::Types types{createTypes()};
- storage.synchronize(modules,
- imports,
- {},
- {sourceId1, qmlModuleSourceId, qtQuickModuleSourceId, pathToModuleSourceId},
- {});
-
- ASSERT_THROW(storage.synchronize({},
- imports,
- types,
- {sourceId1,
- sourceId2,
- qmlModuleSourceId,
- qtQuickModuleSourceId,
- pathToModuleSourceId},
- {}),
- QmlDesigner::ModuleDoesNotExists);
+ auto package{createSimpleSynchronizationPackage()};
+ package.types.push_back(Storage::Type{"QObject2",
+ Storage::ImportedType{},
+ TypeAccessSemantics::Reference,
+ sourceId3,
+ {Storage::ExportedType{ModuleId{22}, "Object2"},
+ Storage::ExportedType{pathToModuleId, "Obj2"}}});
+
+ ASSERT_THROW(storage.synchronize(std::move(package)), QmlDesigner::ModuleDoesNotExists);
}
TEST_F(ProjectStorage, SynchronizeTypesAddsNewTypesReverseOrder)
{
- Storage::Types types{createTypes()};
- std::reverse(types.begin(), types.end());
+ auto package{createSimpleSynchronizationPackage()};
+ std::reverse(package.types.begin(), package.types.end());
- storage.synchronize(
- modules,
- imports,
- types,
- {sourceId1, sourceId2, qmlModuleSourceId, qtQuickModuleSourceId, pathToModuleSourceId},
- {});
+ storage.synchronize(std::move(package));
- ASSERT_THAT(storage.fetchTypes(),
- UnorderedElementsAre(AllOf(IsStorageType(qmlModuleId,
- "QObject",
- Storage::NativeType{},
- TypeAccessSemantics::Reference,
- sourceId2),
- Field(&Storage::Type::exportedTypes,
- UnorderedElementsAre(IsExportedType("Object"),
- IsExportedType("Obj")))),
- AllOf(IsStorageType(qtQuickModuleId,
- "QQuickItem",
- Storage::NativeType{"QObject"},
- TypeAccessSemantics::Reference,
- sourceId1),
- Field(&Storage::Type::exportedTypes,
- UnorderedElementsAre(IsExportedType("Item"))))));
+ ASSERT_THAT(
+ storage.fetchTypes(),
+ UnorderedElementsAre(
+ AllOf(IsStorageType(sourceId2, "QObject", TypeId{}, TypeAccessSemantics::Reference),
+ Field(&Storage::Type::exportedTypes,
+ UnorderedElementsAre(IsExportedType(qmlModuleId, "Object"),
+ IsExportedType(qmlModuleId, "Obj"),
+ IsExportedType(qmlNativeModuleId, "QObject")))),
+ AllOf(IsStorageType(sourceId1,
+ "QQuickItem",
+ fetchTypeId(sourceId2, "QObject"),
+ TypeAccessSemantics::Reference),
+ Field(&Storage::Type::exportedTypes,
+ UnorderedElementsAre(IsExportedType(qtQuickModuleId, "Item"),
+ IsExportedType(qtQuickNativeModuleId, "QQuickItem"))))));
}
TEST_F(ProjectStorage, SynchronizeTypesOverwritesTypeAccessSemantics)
{
- Storage::Types types{createTypes()};
- storage.synchronize(
- modules,
- imports,
- types,
- {sourceId1, sourceId2, qmlModuleSourceId, qtQuickModuleSourceId, pathToModuleSourceId},
- {});
- types[0].accessSemantics = TypeAccessSemantics::Value;
- types[1].accessSemantics = TypeAccessSemantics::Value;
+ auto package{createSimpleSynchronizationPackage()};
+ storage.synchronize(package);
+ package.types[0].accessSemantics = TypeAccessSemantics::Value;
+ package.types[1].accessSemantics = TypeAccessSemantics::Value;
- storage.synchronize({}, imports, types, {sourceId1, sourceId2}, {});
+ storage.synchronize(SynchronizationPackage{package.imports, package.types, {sourceId1, sourceId2}});
ASSERT_THAT(storage.fetchTypes(),
- UnorderedElementsAre(AllOf(IsStorageType(qmlModuleId,
- "QObject",
- Storage::NativeType{},
- TypeAccessSemantics::Value,
- sourceId2),
- Field(&Storage::Type::exportedTypes,
- UnorderedElementsAre(IsExportedType("Object"),
- IsExportedType("Obj")))),
- AllOf(IsStorageType(qtQuickModuleId,
- "QQuickItem",
- Storage::NativeType{"QObject"},
- TypeAccessSemantics::Value,
- sourceId1),
- Field(&Storage::Type::exportedTypes,
- UnorderedElementsAre(IsExportedType("Item"))))));
+ UnorderedElementsAre(
+ AllOf(IsStorageType(sourceId2, "QObject", TypeId{}, TypeAccessSemantics::Value),
+ Field(&Storage::Type::exportedTypes,
+ UnorderedElementsAre(IsExportedType(qmlModuleId, "Object"),
+ IsExportedType(qmlModuleId, "Obj"),
+ IsExportedType(qmlNativeModuleId, "QObject")))),
+ AllOf(IsStorageType(sourceId1,
+ "QQuickItem",
+ fetchTypeId(sourceId2, "QObject"),
+ TypeAccessSemantics::Value),
+ Field(&Storage::Type::exportedTypes,
+ UnorderedElementsAre(IsExportedType(qtQuickModuleId, "Item"),
+ IsExportedType(qtQuickNativeModuleId,
+ "QQuickItem"))))));
}
TEST_F(ProjectStorage, SynchronizeTypesOverwritesSources)
{
- Storage::Types types{createTypes()};
- storage.synchronize(
- modules,
- imports,
- types,
- {sourceId1, sourceId2, qmlModuleSourceId, qtQuickModuleSourceId, pathToModuleSourceId},
- {});
- types[0].sourceId = sourceId3;
- types[1].sourceId = sourceId4;
+ auto package{createSimpleSynchronizationPackage()};
+ storage.synchronize(package);
+ package.types[0].sourceId = sourceId3;
+ package.types[1].sourceId = sourceId4;
Storage::Imports newImports;
- newImports.emplace_back("Qml", Storage::Version{}, sourceId3);
- newImports.emplace_back("Qml", Storage::Version{}, sourceId4);
- newImports.emplace_back("QtQuick", Storage::Version{}, sourceId3);
+ newImports.emplace_back(qmlModuleId, Storage::Version{}, sourceId3);
+ newImports.emplace_back(qmlNativeModuleId, Storage::Version{}, sourceId3);
+ newImports.emplace_back(qtQuickModuleId, Storage::Version{}, sourceId3);
+ newImports.emplace_back(qtQuickNativeModuleId, Storage::Version{}, sourceId3);
+ newImports.emplace_back(qmlModuleId, Storage::Version{}, sourceId4);
+ newImports.emplace_back(qmlNativeModuleId, Storage::Version{}, sourceId4);
- storage.synchronize({}, newImports, types, {sourceId1, sourceId2, sourceId3, sourceId4}, {});
+ storage.synchronize(SynchronizationPackage{newImports,
+ package.types,
+ {sourceId1, sourceId2, sourceId3, sourceId4}});
- ASSERT_THAT(storage.fetchTypes(),
- UnorderedElementsAre(AllOf(IsStorageType(qmlModuleId,
- "QObject",
- Storage::NativeType{},
- TypeAccessSemantics::Reference,
- sourceId4),
- Field(&Storage::Type::exportedTypes,
- UnorderedElementsAre(IsExportedType("Object"),
- IsExportedType("Obj")))),
- AllOf(IsStorageType(qtQuickModuleId,
- "QQuickItem",
- Storage::NativeType{"QObject"},
- TypeAccessSemantics::Reference,
- sourceId3),
- Field(&Storage::Type::exportedTypes,
- UnorderedElementsAre(IsExportedType("Item"))))));
+ ASSERT_THAT(
+ storage.fetchTypes(),
+ UnorderedElementsAre(
+ AllOf(IsStorageType(sourceId4, "QObject", TypeId{}, TypeAccessSemantics::Reference),
+ Field(&Storage::Type::exportedTypes,
+ UnorderedElementsAre(IsExportedType(qmlModuleId, "Object"),
+ IsExportedType(qmlModuleId, "Obj"),
+ IsExportedType(qmlNativeModuleId, "QObject")))),
+ AllOf(IsStorageType(sourceId3,
+ "QQuickItem",
+ fetchTypeId(sourceId4, "QObject"),
+ TypeAccessSemantics::Reference),
+ Field(&Storage::Type::exportedTypes,
+ UnorderedElementsAre(IsExportedType(qtQuickModuleId, "Item"),
+ IsExportedType(qtQuickNativeModuleId, "QQuickItem"))))));
}
TEST_F(ProjectStorage, SynchronizeTypesInsertTypeIntoPrototypeChain)
{
- Storage::Types types{createTypes()};
+ auto package{createSimpleSynchronizationPackage()};
+ storage.synchronize(package);
+ package.types[0].prototype = Storage::ImportedType{"QQuickObject"};
+ package.types.push_back(
+ Storage::Type{"QQuickObject",
+ Storage::ImportedType{"QObject"},
+ TypeAccessSemantics::Reference,
+ sourceId1,
+ {Storage::ExportedType{qtQuickModuleId, "Object"},
+ Storage::ExportedType{qtQuickNativeModuleId, "QQuickObject"}}});
+
storage.synchronize(
- modules,
- imports,
- types,
- {sourceId1, sourceId2, qmlModuleSourceId, qtQuickModuleSourceId, pathToModuleSourceId},
- {});
- types[0].prototype = Storage::NativeType{"QQuickObject"};
- types.push_back(Storage::Type{qtQuickModuleId,
- "QQuickObject",
- Storage::NativeType{"QObject"},
- TypeAccessSemantics::Reference,
- sourceId1,
- {Storage::ExportedType{"Object"}}});
-
- storage.synchronize({}, importsSourceId1, {types[0], types[2]}, {sourceId1}, {});
+ SynchronizationPackage{importsSourceId1, {package.types[0], package.types[2]}, {sourceId1}});
- ASSERT_THAT(storage.fetchTypes(),
- UnorderedElementsAre(AllOf(IsStorageType(qmlModuleId,
- "QObject",
- Storage::NativeType{},
- TypeAccessSemantics::Reference,
- sourceId2),
- Field(&Storage::Type::exportedTypes,
- UnorderedElementsAre(IsExportedType("Object"),
- IsExportedType("Obj")))),
- AllOf(IsStorageType(qtQuickModuleId,
- "QQuickObject",
- Storage::NativeType{"QObject"},
- TypeAccessSemantics::Reference,
- sourceId1),
- Field(&Storage::Type::exportedTypes,
- UnorderedElementsAre(IsExportedType("Object")))),
- AllOf(IsStorageType(qtQuickModuleId,
- "QQuickItem",
- Storage::NativeType{"QQuickObject"},
- TypeAccessSemantics::Reference,
- sourceId1),
- Field(&Storage::Type::exportedTypes,
- UnorderedElementsAre(IsExportedType("Item"))))));
+ ASSERT_THAT(
+ storage.fetchTypes(),
+ UnorderedElementsAre(
+ AllOf(IsStorageType(sourceId2, "QObject", TypeId{}, TypeAccessSemantics::Reference),
+ Field(&Storage::Type::exportedTypes,
+ UnorderedElementsAre(IsExportedType(qmlModuleId, "Object"),
+ IsExportedType(qmlModuleId, "Obj"),
+ IsExportedType(qmlNativeModuleId, "QObject")))),
+ AllOf(IsStorageType(sourceId1,
+ "QQuickObject",
+ fetchTypeId(sourceId2, "QObject"),
+ TypeAccessSemantics::Reference),
+ Field(&Storage::Type::exportedTypes,
+ UnorderedElementsAre(IsExportedType(qtQuickModuleId, "Object"),
+ IsExportedType(qtQuickNativeModuleId, "QQuickObject")))),
+ AllOf(IsStorageType(sourceId1,
+ "QQuickItem",
+ fetchTypeId(sourceId1, "QQuickObject"),
+ TypeAccessSemantics::Reference),
+ Field(&Storage::Type::exportedTypes,
+ UnorderedElementsAre(IsExportedType(qtQuickModuleId, "Item"),
+ IsExportedType(qtQuickNativeModuleId, "QQuickItem"))))));
}
TEST_F(ProjectStorage, SynchronizeTypesAddQualifiedPrototype)
{
- Storage::Types types{createTypes()};
- types[0].prototype = Storage::QualifiedImportedType{"Object",
- Storage::Import{"QtQuick",
- Storage::Version{},
- sourceId1}};
- types.push_back(Storage::Type{qtQuickModuleId,
- "QQuickObject",
- Storage::NativeType{"QObject"},
- TypeAccessSemantics::Reference,
- sourceId1,
- {Storage::ExportedType{"Object"}}});
+ auto package{createSimpleSynchronizationPackage()};
+ package.types[0].prototype = Storage::QualifiedImportedType{"Object",
+ Storage::Import{qtQuickModuleId,
+ Storage::Version{},
+ sourceId1}};
+ package.types.push_back(
+ Storage::Type{"QQuickObject",
+ Storage::ImportedType{"QObject"},
+ TypeAccessSemantics::Reference,
+ sourceId1,
+ {Storage::ExportedType{qtQuickModuleId, "Object"},
+ Storage::ExportedType{qtQuickNativeModuleId, "QQuickObject"}}});
+
+ storage.synchronize(package);
- storage.synchronize(
- modules,
- imports,
- types,
- {sourceId1, sourceId2, qmlModuleSourceId, qtQuickModuleSourceId, pathToModuleSourceId},
- {});
-
- ASSERT_THAT(storage.fetchTypes(),
- UnorderedElementsAre(AllOf(IsStorageType(qmlModuleId,
- "QObject",
- Storage::NativeType{},
- TypeAccessSemantics::Reference,
- sourceId2),
- Field(&Storage::Type::exportedTypes,
- UnorderedElementsAre(IsExportedType("Object"),
- IsExportedType("Obj")))),
- AllOf(IsStorageType(qtQuickModuleId,
- "QQuickObject",
- Storage::NativeType{"QObject"},
- TypeAccessSemantics::Reference,
- sourceId1),
- Field(&Storage::Type::exportedTypes,
- UnorderedElementsAre(IsExportedType("Object")))),
- AllOf(IsStorageType(qtQuickModuleId,
- "QQuickItem",
- Storage::NativeType{"QQuickObject"},
- TypeAccessSemantics::Reference,
- sourceId1),
- Field(&Storage::Type::exportedTypes,
- UnorderedElementsAre(IsExportedType("Item"))))));
+ ASSERT_THAT(
+ storage.fetchTypes(),
+ UnorderedElementsAre(
+ AllOf(IsStorageType(sourceId2, "QObject", TypeId{}, TypeAccessSemantics::Reference),
+ Field(&Storage::Type::exportedTypes,
+ UnorderedElementsAre(IsExportedType(qmlModuleId, "Object"),
+ IsExportedType(qmlModuleId, "Obj"),
+ IsExportedType(qmlNativeModuleId, "QObject")))),
+ AllOf(IsStorageType(sourceId1,
+ "QQuickObject",
+ fetchTypeId(sourceId2, "QObject"),
+ TypeAccessSemantics::Reference),
+ Field(&Storage::Type::exportedTypes,
+ UnorderedElementsAre(IsExportedType(qtQuickModuleId, "Object"),
+ IsExportedType(qtQuickNativeModuleId, "QQuickObject")))),
+ AllOf(IsStorageType(sourceId1,
+ "QQuickItem",
+ fetchTypeId(sourceId1, "QQuickObject"),
+ TypeAccessSemantics::Reference),
+ Field(&Storage::Type::exportedTypes,
+ UnorderedElementsAre(IsExportedType(qtQuickModuleId, "Item"),
+ IsExportedType(qtQuickNativeModuleId, "QQuickItem"))))));
}
TEST_F(ProjectStorage, SynchronizeTypesThrowsForMissingPrototype)
{
- sourceId1 = sourcePathCache.sourceId(path1);
- Storage::Types types{Storage::Type{qtQuickModuleId,
- "QQuickItem",
- Storage::NativeType{"QObject"},
- TypeAccessSemantics::Reference,
- sourceId1,
- {Storage::ExportedType{"Item"}}}};
+ auto package{createSimpleSynchronizationPackage()};
+ package.types = {Storage::Type{"QQuickItem",
+ Storage::ImportedType{"QObject"},
+ TypeAccessSemantics::Reference,
+ sourceId1,
+ {Storage::ExportedType{qtQuickModuleId, "Item"},
+ Storage::ExportedType{qtQuickNativeModuleId, "QQuickItem"}}}};
- ASSERT_THROW(storage.synchronize(
- modules,
- imports,
- types,
- {sourceId1, qmlModuleSourceId, qtQuickModuleSourceId, pathToModuleSourceId},
- {}),
- QmlDesigner::TypeNameDoesNotExists);
+ ASSERT_THROW(storage.synchronize(package), QmlDesigner::TypeNameDoesNotExists);
}
TEST_F(ProjectStorage, SynchronizeTypesThrowsForInvalidModule)
{
- sourceId1 = sourcePathCache.sourceId(path1);
- Storage::Types types{Storage::Type{ModuleId{},
- "QQuickItem",
- Storage::NativeType{"QObject"},
- TypeAccessSemantics::Reference,
- sourceId1,
- {Storage::ExportedType{"Item"}}}};
+ auto package{createSimpleSynchronizationPackage()};
+ package.types = {Storage::Type{"QQuickItem",
+ Storage::ImportedType{"QObject"},
+ TypeAccessSemantics::Reference,
+ sourceId1,
+ {Storage::ExportedType{ModuleId{}, "Item"}}}};
- ASSERT_THROW(storage.synchronize({}, imports, types, {sourceId1}, {}),
- QmlDesigner::ModuleDoesNotExists);
+ ASSERT_THROW(storage.synchronize(package), QmlDesigner::ModuleDoesNotExists);
}
TEST_F(ProjectStorage, TypeWithInvalidSourceIdThrows)
{
- Storage::Types types{Storage::Type{qtQuickModuleId,
- "QQuickItem",
- Storage::NativeType{""},
- TypeAccessSemantics::Reference,
- SourceId{},
- {Storage::ExportedType{"Item"}}}};
+ auto package{createSimpleSynchronizationPackage()};
+ package.types = {Storage::Type{"QQuickItem",
+ Storage::ImportedType{""},
+ TypeAccessSemantics::Reference,
+ SourceId{},
+ {Storage::ExportedType{qtQuickModuleId, "Item"}}}};
- ASSERT_THROW(storage.synchronize(
- modules,
- imports,
- types,
- {sourceId1, qmlModuleSourceId, qtQuickModuleSourceId, pathToModuleSourceId},
- {}),
- QmlDesigner::TypeHasInvalidSourceId);
+ ASSERT_THROW(storage.synchronize(package), QmlDesigner::TypeHasInvalidSourceId);
}
TEST_F(ProjectStorage, DeleteTypeIfSourceIdIsSynchronized)
{
- Storage::Types types{createTypes()};
- storage.synchronize(
- modules,
- imports,
- types,
- {sourceId1, sourceId2, qmlModuleSourceId, qtQuickModuleSourceId, pathToModuleSourceId},
- {});
- types.erase(types.begin());
+ auto package{createSimpleSynchronizationPackage()};
+ storage.synchronize(package);
+ package.types.erase(package.types.begin());
- storage.synchronize({}, importsSourceId2, types, {sourceId1, sourceId2}, {});
+ storage.synchronize(package);
ASSERT_THAT(storage.fetchTypes(),
- UnorderedElementsAre(AllOf(IsStorageType(qmlModuleId,
- "QObject",
- Storage::NativeType{},
- TypeAccessSemantics::Reference,
- sourceId2),
- Field(&Storage::Type::exportedTypes,
- UnorderedElementsAre(IsExportedType("Object"),
- IsExportedType("Obj"))))));
+ UnorderedElementsAre(
+ AllOf(IsStorageType(sourceId2, "QObject", TypeId{}, TypeAccessSemantics::Reference),
+ Field(&Storage::Type::exportedTypes,
+ UnorderedElementsAre(IsExportedType(qmlModuleId, "Object"),
+ IsExportedType(qmlModuleId, "Obj"),
+ IsExportedType(qmlNativeModuleId, "QObject"))))));
}
TEST_F(ProjectStorage, DontDeleteTypeIfSourceIdIsNotSynchronized)
{
- Storage::Types types{createTypes()};
- storage.synchronize(
- modules,
- imports,
- types,
- {sourceId1, sourceId2, qmlModuleSourceId, qtQuickModuleSourceId, pathToModuleSourceId},
- {});
- types.pop_back();
+ auto package{createSimpleSynchronizationPackage()};
+ storage.synchronize(package);
- storage.synchronize({}, importsSourceId1, types, {sourceId1}, {});
+ storage.synchronize(SynchronizationPackage{importsSourceId1, {package.types[0]}, {sourceId1}});
- ASSERT_THAT(storage.fetchTypes(),
- UnorderedElementsAre(AllOf(IsStorageType(qmlModuleId,
- "QObject",
- Storage::NativeType{},
- TypeAccessSemantics::Reference,
- sourceId2),
- Field(&Storage::Type::exportedTypes,
- UnorderedElementsAre(IsExportedType("Object"),
- IsExportedType("Obj")))),
- AllOf(IsStorageType(qtQuickModuleId,
- "QQuickItem",
- Storage::NativeType{"QObject"},
- TypeAccessSemantics::Reference,
- sourceId1),
- Field(&Storage::Type::exportedTypes,
- UnorderedElementsAre(IsExportedType("Item"))))));
+ ASSERT_THAT(
+ storage.fetchTypes(),
+ UnorderedElementsAre(
+ AllOf(IsStorageType(sourceId2, "QObject", TypeId{}, TypeAccessSemantics::Reference),
+ Field(&Storage::Type::exportedTypes,
+ UnorderedElementsAre(IsExportedType(qmlModuleId, "Object"),
+ IsExportedType(qmlModuleId, "Obj"),
+ IsExportedType(qmlNativeModuleId, "QObject")))),
+ AllOf(IsStorageType(sourceId1,
+ "QQuickItem",
+ fetchTypeId(sourceId2, "QObject"),
+ TypeAccessSemantics::Reference),
+ Field(&Storage::Type::exportedTypes,
+ UnorderedElementsAre(IsExportedType(qtQuickModuleId, "Item"),
+ IsExportedType(qtQuickNativeModuleId, "QQuickItem"))))));
}
TEST_F(ProjectStorage, UpdateExportedTypesIfTypeNameChanges)
{
- Storage::Types types{createTypes()};
- storage.synchronize(
- modules,
- imports,
- types,
- {sourceId1, sourceId2, qmlModuleSourceId, qtQuickModuleSourceId, pathToModuleSourceId},
- {});
- types[0].typeName = "QQuickItem2";
+ auto package{createSimpleSynchronizationPackage()};
+ storage.synchronize(package);
+ package.types[0].typeName = "QQuickItem2";
- storage.synchronize({}, importsSourceId1, {types[0]}, {sourceId1}, {});
+ storage.synchronize(SynchronizationPackage{importsSourceId1, {package.types[0]}, {sourceId1}});
- ASSERT_THAT(storage.fetchTypes(),
- UnorderedElementsAre(AllOf(IsStorageType(qmlModuleId,
- "QObject",
- Storage::NativeType{},
- TypeAccessSemantics::Reference,
- sourceId2),
- Field(&Storage::Type::exportedTypes,
- UnorderedElementsAre(IsExportedType("Object"),
- IsExportedType("Obj")))),
- AllOf(IsStorageType(qtQuickModuleId,
- "QQuickItem2",
- Storage::NativeType{"QObject"},
- TypeAccessSemantics::Reference,
- sourceId1),
- Field(&Storage::Type::exportedTypes,
- UnorderedElementsAre(IsExportedType("Item"))))));
+ ASSERT_THAT(
+ storage.fetchTypes(),
+ UnorderedElementsAre(
+ AllOf(IsStorageType(sourceId2, "QObject", TypeId{}, TypeAccessSemantics::Reference),
+ Field(&Storage::Type::exportedTypes,
+ UnorderedElementsAre(IsExportedType(qmlModuleId, "Object"),
+ IsExportedType(qmlModuleId, "Obj"),
+ IsExportedType(qmlNativeModuleId, "QObject")))),
+ AllOf(IsStorageType(sourceId1,
+ "QQuickItem2",
+ fetchTypeId(sourceId2, "QObject"),
+ TypeAccessSemantics::Reference),
+ Field(&Storage::Type::exportedTypes,
+ UnorderedElementsAre(IsExportedType(qtQuickModuleId, "Item"),
+ IsExportedType(qtQuickNativeModuleId, "QQuickItem"))))));
}
TEST_F(ProjectStorage, BreakingPrototypeChainByDeletingBaseComponentThrows)
{
- Storage::Types types{createTypes()};
- storage.synchronize(
- modules,
- imports,
- types,
- {sourceId1, sourceId2, qmlModuleSourceId, qtQuickModuleSourceId, pathToModuleSourceId},
- {});
- types.pop_back();
-
- ASSERT_THROW(storage.synchronize({}, importsSourceId1, types, {sourceId1, sourceId2}, {}),
+ auto package{createSimpleSynchronizationPackage()};
+ storage.synchronize(package);
+
+ ASSERT_THROW(storage.synchronize(SynchronizationPackage{importsSourceId1,
+ {package.types[0]},
+ {sourceId1, sourceId2}}),
QmlDesigner::TypeNameDoesNotExists);
}
TEST_F(ProjectStorage, SynchronizeTypesAddPropertyDeclarations)
{
- Storage::Types types{createTypes()};
+ auto package{createSimpleSynchronizationPackage()};
- storage.synchronize(
- modules,
- imports,
- types,
- {sourceId1, sourceId2, qmlModuleSourceId, qtQuickModuleSourceId, pathToModuleSourceId},
- {});
+ storage.synchronize(package);
ASSERT_THAT(storage.fetchTypes(),
Contains(
- AllOf(IsStorageType(qtQuickModuleId,
+ AllOf(IsStorageType(sourceId1,
"QQuickItem",
- Storage::NativeType{"QObject"},
- TypeAccessSemantics::Reference,
- sourceId1),
+ fetchTypeId(sourceId2, "QObject"),
+ TypeAccessSemantics::Reference),
Field(&Storage::Type::propertyDeclarations,
UnorderedElementsAre(
IsPropertyDeclaration("data",
- Storage::NativeType{"QObject"},
+ fetchTypeId(sourceId2, "QObject"),
Storage::PropertyDeclarationTraits::IsList),
IsPropertyDeclaration(
"children",
- Storage::NativeType{"QQuickItem"},
+ fetchTypeId(sourceId1, "QQuickItem"),
Storage::PropertyDeclarationTraits::IsList
| Storage::PropertyDeclarationTraits::IsReadOnly))))));
}
-TEST_F(ProjectStorage, SynchronizeTypesAddPropertyDeclarationsWithMissingImportsForNativeTypes)
+TEST_F(ProjectStorage, SynchronizeTypesAddPropertyDeclarationsWithMissingImports)
{
- Storage::Types types{createTypes()};
- types[0].propertyDeclarations.pop_back();
+ auto package{createSimpleSynchronizationPackage()};
+ package.imports.clear();
- ASSERT_THROW(storage.synchronize(modules,
- {},
- types,
- {sourceId1,
- sourceId2,
- qmlModuleSourceId,
- qtQuickModuleSourceId,
- pathToModuleSourceId},
- {}),
- QmlDesigner::TypeNameDoesNotExists);
-}
-
-TEST_F(ProjectStorage, SynchronizeTypesAddPropertyDeclarationsWithMissingImportsForExportedTypes)
-{
- Storage::Types types{createTypes()};
- storage.synchronize(
- modules,
- imports,
- types,
- {sourceId1, sourceId2, qmlModuleSourceId, qtQuickModuleSourceId, pathToModuleSourceId},
- {});
- types[0].propertyDeclarations[0].typeName = Storage::ImportedType{"Obj"};
-
- ASSERT_THROW(storage.synchronize({}, {}, {types[0]}, {sourceId1}, {}),
- QmlDesigner::TypeNameDoesNotExists);
+ ASSERT_THROW(storage.synchronize(package), QmlDesigner::TypeNameDoesNotExists);
}
TEST_F(ProjectStorage, SynchronizeTypesAddPropertyDeclarationQualifiedType)
{
- Storage::Types types{createTypes()};
- types[0].propertyDeclarations[0].typeName = Storage::QualifiedImportedType{
- "Object", Storage::Import{"QtQuick", Storage::Version{}, sourceId1}};
- types.push_back(Storage::Type{qtQuickModuleId,
- "QQuickObject",
- Storage::NativeType{"QObject"},
- TypeAccessSemantics::Reference,
- sourceId1,
- {Storage::ExportedType{"Object"}}});
+ auto package{createSimpleSynchronizationPackage()};
+ package.types[0].propertyDeclarations[0].typeName = Storage::QualifiedImportedType{
+ "Object", Storage::Import{qtQuickModuleId, Storage::Version{}, sourceId1}};
+ package.types.push_back(Storage::Type{"QQuickObject",
+ Storage::ImportedType{"QObject"},
+ TypeAccessSemantics::Reference,
+ sourceId1,
+ {Storage::ExportedType{qtQuickModuleId, "Object"}}});
- storage.synchronize(
- modules,
- imports,
- types,
- {sourceId1, sourceId2, qmlModuleSourceId, qtQuickModuleSourceId, pathToModuleSourceId},
- {});
+ storage.synchronize(package);
ASSERT_THAT(storage.fetchTypes(),
Contains(
- AllOf(IsStorageType(qtQuickModuleId,
+ AllOf(IsStorageType(sourceId1,
"QQuickItem",
- Storage::NativeType{"QObject"},
- TypeAccessSemantics::Reference,
- sourceId1),
+ fetchTypeId(sourceId2, "QObject"),
+ TypeAccessSemantics::Reference),
Field(&Storage::Type::propertyDeclarations,
UnorderedElementsAre(
IsPropertyDeclaration("data",
- Storage::NativeType{"QQuickObject"},
+ fetchTypeId(sourceId1, "QQuickObject"),
Storage::PropertyDeclarationTraits::IsList),
IsPropertyDeclaration(
"children",
- Storage::NativeType{"QQuickItem"},
+ fetchTypeId(sourceId1, "QQuickItem"),
Storage::PropertyDeclarationTraits::IsList
| Storage::PropertyDeclarationTraits::IsReadOnly))))));
}
TEST_F(ProjectStorage, SynchronizeTypesChangesPropertyDeclarationType)
{
- Storage::Types types{createTypes()};
- storage.synchronize(
- modules,
- imports,
- types,
- {sourceId1, sourceId2, qmlModuleSourceId, qtQuickModuleSourceId, pathToModuleSourceId},
- {});
- types[0].propertyDeclarations[0].typeName = Storage::NativeType{"QQuickItem"};
-
- storage.synchronize({}, importsSourceId1, {types[0]}, {sourceId1}, {});
+ auto package{createSimpleSynchronizationPackage()};
+ storage.synchronize(package);
+ package.types[0].propertyDeclarations[0].typeName = Storage::ImportedType{"QQuickItem"};
+
+ storage.synchronize(SynchronizationPackage{importsSourceId1, {package.types[0]}, {sourceId1}});
+
ASSERT_THAT(storage.fetchTypes(),
Contains(
- AllOf(IsStorageType(qtQuickModuleId,
+ AllOf(IsStorageType(sourceId1,
"QQuickItem",
- Storage::NativeType{"QObject"},
- TypeAccessSemantics::Reference,
- sourceId1),
+ fetchTypeId(sourceId2, "QObject"),
+ TypeAccessSemantics::Reference),
Field(&Storage::Type::propertyDeclarations,
UnorderedElementsAre(
IsPropertyDeclaration("data",
- Storage::NativeType{"QQuickItem"},
+ fetchTypeId(sourceId1, "QQuickItem"),
Storage::PropertyDeclarationTraits::IsList),
IsPropertyDeclaration(
"children",
- Storage::NativeType{"QQuickItem"},
+ fetchTypeId(sourceId1, "QQuickItem"),
Storage::PropertyDeclarationTraits::IsList
| Storage::PropertyDeclarationTraits::IsReadOnly))))));
}
TEST_F(ProjectStorage, SynchronizeTypesChangesDeclarationTraits)
{
- Storage::Types types{createTypes()};
- storage.synchronize(
- modules,
- imports,
- types,
- {sourceId1, sourceId2, qmlModuleSourceId, qtQuickModuleSourceId, pathToModuleSourceId},
- {});
- types[0].propertyDeclarations[0].traits = Storage::PropertyDeclarationTraits::IsPointer;
+ auto package{createSimpleSynchronizationPackage()};
+ storage.synchronize(package);
+ package.types[0].propertyDeclarations[0].traits = Storage::PropertyDeclarationTraits::IsPointer;
- storage.synchronize({}, importsSourceId1, {types[0]}, {sourceId1}, {});
+ storage.synchronize(SynchronizationPackage{importsSourceId1, {package.types[0]}, {sourceId1}});
ASSERT_THAT(storage.fetchTypes(),
Contains(
- AllOf(IsStorageType(qtQuickModuleId,
+ AllOf(IsStorageType(sourceId1,
"QQuickItem",
- Storage::NativeType{"QObject"},
- TypeAccessSemantics::Reference,
- sourceId1),
+ fetchTypeId(sourceId2, "QObject"),
+ TypeAccessSemantics::Reference),
Field(&Storage::Type::propertyDeclarations,
UnorderedElementsAre(
IsPropertyDeclaration("data",
- Storage::NativeType{"QObject"},
+ fetchTypeId(sourceId2, "QObject"),
Storage::PropertyDeclarationTraits::IsPointer),
IsPropertyDeclaration(
"children",
- Storage::NativeType{"QQuickItem"},
+ fetchTypeId(sourceId1, "QQuickItem"),
Storage::PropertyDeclarationTraits::IsList
| Storage::PropertyDeclarationTraits::IsReadOnly))))));
}
TEST_F(ProjectStorage, SynchronizeTypesChangesDeclarationTraitsAndType)
{
- Storage::Types types{createTypes()};
- storage.synchronize(
- modules,
- imports,
- types,
- {sourceId1, sourceId2, qmlModuleSourceId, qtQuickModuleSourceId, pathToModuleSourceId},
- {});
- types[0].propertyDeclarations[0].traits = Storage::PropertyDeclarationTraits::IsPointer;
- types[0].propertyDeclarations[0].typeName = Storage::NativeType{"QQuickItem"};
+ auto package{createSimpleSynchronizationPackage()};
+ storage.synchronize(package);
+ package.types[0].propertyDeclarations[0].traits = Storage::PropertyDeclarationTraits::IsPointer;
+ package.types[0].propertyDeclarations[0].typeName = Storage::ImportedType{"QQuickItem"};
- storage.synchronize({}, importsSourceId1, {types[0]}, {sourceId1}, {});
+ storage.synchronize(SynchronizationPackage{importsSourceId1, {package.types[0]}, {sourceId1}});
ASSERT_THAT(storage.fetchTypes(),
Contains(
- AllOf(IsStorageType(qtQuickModuleId,
+ AllOf(IsStorageType(sourceId1,
"QQuickItem",
- Storage::NativeType{"QObject"},
- TypeAccessSemantics::Reference,
- sourceId1),
+ fetchTypeId(sourceId2, "QObject"),
+ TypeAccessSemantics::Reference),
Field(&Storage::Type::propertyDeclarations,
UnorderedElementsAre(
IsPropertyDeclaration("data",
- Storage::NativeType{"QQuickItem"},
+ fetchTypeId(sourceId1, "QQuickItem"),
Storage::PropertyDeclarationTraits::IsPointer),
IsPropertyDeclaration(
"children",
- Storage::NativeType{"QQuickItem"},
+ fetchTypeId(sourceId1, "QQuickItem"),
Storage::PropertyDeclarationTraits::IsList
| Storage::PropertyDeclarationTraits::IsReadOnly))))));
}
TEST_F(ProjectStorage, SynchronizeTypesRemovesAPropertyDeclaration)
{
- Storage::Types types{createTypes()};
- storage.synchronize(
- modules,
- imports,
- types,
- {sourceId1, sourceId2, qmlModuleSourceId, qtQuickModuleSourceId, pathToModuleSourceId},
- {});
- types[0].propertyDeclarations.pop_back();
+ auto package{createSimpleSynchronizationPackage()};
+ storage.synchronize(package);
+ package.types[0].propertyDeclarations.pop_back();
- storage.synchronize({}, importsSourceId1, {types[0]}, {sourceId1}, {});
+ storage.synchronize(SynchronizationPackage{importsSourceId1, {package.types[0]}, {sourceId1}});
ASSERT_THAT(storage.fetchTypes(),
- Contains(AllOf(IsStorageType(qtQuickModuleId,
+ Contains(AllOf(IsStorageType(sourceId1,
"QQuickItem",
- Storage::NativeType{"QObject"},
- TypeAccessSemantics::Reference,
- sourceId1),
+ fetchTypeId(sourceId2, "QObject"),
+ TypeAccessSemantics::Reference),
Field(&Storage::Type::propertyDeclarations,
UnorderedElementsAre(IsPropertyDeclaration(
"data",
- Storage::NativeType{"QObject"},
+ fetchTypeId(sourceId2, "QObject"),
Storage::PropertyDeclarationTraits::IsList))))));
}
TEST_F(ProjectStorage, SynchronizeTypesAddsAPropertyDeclaration)
{
- Storage::Types types{createTypes()};
- storage.synchronize(
- modules,
- imports,
- types,
- {sourceId1, sourceId2, qmlModuleSourceId, qtQuickModuleSourceId, pathToModuleSourceId},
- {});
- types[0].propertyDeclarations.push_back(
+ auto package{createSimpleSynchronizationPackage()};
+ storage.synchronize(package);
+ package.types[0].propertyDeclarations.push_back(
Storage::PropertyDeclaration{"object",
- Storage::NativeType{"QObject"},
+ Storage::ImportedType{"QObject"},
Storage::PropertyDeclarationTraits::IsPointer});
- storage.synchronize({}, importsSourceId1, {types[0]}, {sourceId1}, {});
+ storage.synchronize(SynchronizationPackage{importsSourceId1, {package.types[0]}, {sourceId1}});
ASSERT_THAT(
storage.fetchTypes(),
Contains(AllOf(
- IsStorageType(qtQuickModuleId,
+ IsStorageType(sourceId1,
"QQuickItem",
- Storage::NativeType{"QObject"},
- TypeAccessSemantics::Reference,
- sourceId1),
+ fetchTypeId(sourceId2, "QObject"),
+ TypeAccessSemantics::Reference),
Field(&Storage::Type::propertyDeclarations,
UnorderedElementsAre(
IsPropertyDeclaration("object",
- Storage::NativeType{"QObject"},
+ fetchTypeId(sourceId2, "QObject"),
Storage::PropertyDeclarationTraits::IsPointer),
IsPropertyDeclaration("data",
- Storage::NativeType{"QObject"},
+ fetchTypeId(sourceId2, "QObject"),
Storage::PropertyDeclarationTraits::IsList),
IsPropertyDeclaration("children",
- Storage::NativeType{"QQuickItem"},
+ fetchTypeId(sourceId1, "QQuickItem"),
Storage::PropertyDeclarationTraits::IsList
| Storage::PropertyDeclarationTraits::IsReadOnly))))));
}
TEST_F(ProjectStorage, SynchronizeTypesRenameAPropertyDeclaration)
{
- Storage::Types types{createTypes()};
- storage.synchronize(
- modules,
- imports,
- types,
- {sourceId1, sourceId2, qmlModuleSourceId, qtQuickModuleSourceId, pathToModuleSourceId},
- {});
- types[0].propertyDeclarations[1].name = "objects";
+ auto package{createSimpleSynchronizationPackage()};
+ storage.synchronize(package);
+ package.types[0].propertyDeclarations[1].name = "objects";
- storage.synchronize({}, importsSourceId1, {types[0]}, {sourceId1}, {});
+ storage.synchronize(SynchronizationPackage{importsSourceId1, {package.types[0]}, {sourceId1}});
ASSERT_THAT(storage.fetchTypes(),
Contains(
- AllOf(IsStorageType(qtQuickModuleId,
+ AllOf(IsStorageType(sourceId1,
"QQuickItem",
- Storage::NativeType{"QObject"},
- TypeAccessSemantics::Reference,
- sourceId1),
+ fetchTypeId(sourceId2, "QObject"),
+ TypeAccessSemantics::Reference),
Field(&Storage::Type::propertyDeclarations,
UnorderedElementsAre(
IsPropertyDeclaration("data",
- Storage::NativeType{"QObject"},
+ fetchTypeId(sourceId2, "QObject"),
Storage::PropertyDeclarationTraits::IsList),
IsPropertyDeclaration(
"objects",
- Storage::NativeType{"QQuickItem"},
+ fetchTypeId(sourceId1, "QQuickItem"),
Storage::PropertyDeclarationTraits::IsList
| Storage::PropertyDeclarationTraits::IsReadOnly))))));
}
-TEST_F(ProjectStorage, UsingNonExistingNativePropertyTypeThrows)
+TEST_F(ProjectStorage, UsingNonExistingPropertyTypeThrows)
{
- Storage::Types types{createTypes()};
- types[0].propertyDeclarations[0].typeName = Storage::NativeType{"QObject2"};
- types.pop_back();
+ auto package{createSimpleSynchronizationPackage()};
+ package.types[0].propertyDeclarations[0].typeName = Storage::ImportedType{"QObject2"};
+ package.types.pop_back();
+ package.imports = importsSourceId1;
- ASSERT_THROW(storage.synchronize(modules,
- importsSourceId1,
- types,
- {sourceId1,
- sourceId2,
- qmlModuleSourceId,
- qtQuickModuleSourceId,
- pathToModuleSourceId},
- {}),
- QmlDesigner::TypeNameDoesNotExists);
-}
-
-TEST_F(ProjectStorage, UsingNonExistingExportedPropertyTypeThrows)
-{
- Storage::Types types{createTypes()};
- types[0].propertyDeclarations[0].typeName = Storage::ImportedType{"QObject2"};
- types.pop_back();
-
- ASSERT_THROW(storage.synchronize(modules,
- importsSourceId1,
- types,
- {sourceId1,
- sourceId2,
- qmlModuleSourceId,
- qtQuickModuleSourceId,
- pathToModuleSourceId},
- {}),
- QmlDesigner::TypeNameDoesNotExists);
+ ASSERT_THROW(storage.synchronize(package), QmlDesigner::TypeNameDoesNotExists);
}
TEST_F(ProjectStorage, UsingNonExistingQualifiedExportedPropertyTypeWithWrongNameThrows)
{
- Storage::Types types{createTypes()};
- types[0].propertyDeclarations[0].typeName = Storage::QualifiedImportedType{
- "QObject2", Storage::Import{"Qml", Storage::Version{}, sourceId1}};
- types.pop_back();
-
- ASSERT_THROW(storage.synchronize(modules,
- importsSourceId1,
- types,
- {sourceId1,
- sourceId2,
- qmlModuleSourceId,
- qtQuickModuleSourceId,
- pathToModuleSourceId},
- {}),
- QmlDesigner::TypeNameDoesNotExists);
+ auto package{createSimpleSynchronizationPackage()};
+ package.types[0].propertyDeclarations[0].typeName = Storage::QualifiedImportedType{
+ "QObject2", Storage::Import{qmlNativeModuleId, Storage::Version{}, sourceId1}};
+ package.types.pop_back();
+ package.imports = importsSourceId1;
+
+ ASSERT_THROW(storage.synchronize(package), QmlDesigner::TypeNameDoesNotExists);
}
TEST_F(ProjectStorage, UsingNonExistingQualifiedExportedPropertyTypeWithWrongModuleThrows)
{
- Storage::Types types{createTypes()};
- types[0].propertyDeclarations[0].typeName = Storage::QualifiedImportedType{
- "QObject", Storage::Import{"QtQuick", Storage::Version{}, sourceId1}};
- types.pop_back();
-
- ASSERT_THROW(storage.synchronize(modules,
- importsSourceId1,
- types,
- {sourceId1,
- sourceId2,
- qmlModuleSourceId,
- qtQuickModuleSourceId,
- pathToModuleSourceId},
- {}),
- QmlDesigner::TypeNameDoesNotExists);
+ auto package{createSimpleSynchronizationPackage()};
+ package.types[0].propertyDeclarations[0].typeName = Storage::QualifiedImportedType{
+ "QObject", Storage::Import{qmlModuleId, Storage::Version{}, sourceId1}};
+ package.types.pop_back();
+ package.imports = importsSourceId1;
+
+ ASSERT_THROW(storage.synchronize(package), QmlDesigner::TypeNameDoesNotExists);
}
TEST_F(ProjectStorage, BreakingPropertyDeclarationTypeDependencyByDeletingTypeThrows)
{
- Storage::Types types{createTypes()};
- storage.synchronize(
- modules,
- imports,
- types,
- {sourceId1, sourceId2, qmlModuleSourceId, qtQuickModuleSourceId, pathToModuleSourceId},
- {});
- types[0].prototype = Storage::NativeType{};
- types.pop_back();
-
- ASSERT_THROW(storage.synchronize(modules,
- importsSourceId1,
- types,
- {sourceId1,
- sourceId2,
- qmlModuleSourceId,
- qtQuickModuleSourceId,
- pathToModuleSourceId},
- {}),
- QmlDesigner::TypeNameDoesNotExists);
+ auto package{createSimpleSynchronizationPackage()};
+ storage.synchronize(package);
+ package.types[0].prototype = Storage::ImportedType{};
+ package.types.pop_back();
+ package.imports = importsSourceId1;
+
+ ASSERT_THROW(storage.synchronize(package), QmlDesigner::TypeNameDoesNotExists);
}
TEST_F(ProjectStorage, SynchronizeTypesAddFunctionDeclarations)
{
- Storage::Types types{createTypes()};
+ auto package{createSimpleSynchronizationPackage()};
- storage.synchronize(
- modules,
- imports,
- types,
- {sourceId1, sourceId2, qmlModuleSourceId, qtQuickModuleSourceId, pathToModuleSourceId},
- {});
+ storage.synchronize(package);
ASSERT_THAT(storage.fetchTypes(),
- Contains(AllOf(IsStorageType(qtQuickModuleId,
- "QQuickItem",
- Storage::NativeType{"QObject"},
- TypeAccessSemantics::Reference,
- sourceId1),
- Field(&Storage::Type::functionDeclarations,
- UnorderedElementsAre(Eq(types[0].functionDeclarations[0]),
- Eq(types[0].functionDeclarations[1]))))));
+ Contains(
+ AllOf(IsStorageType(sourceId1,
+ "QQuickItem",
+ fetchTypeId(sourceId2, "QObject"),
+ TypeAccessSemantics::Reference),
+ Field(&Storage::Type::functionDeclarations,
+ UnorderedElementsAre(Eq(package.types[0].functionDeclarations[0]),
+ Eq(package.types[0].functionDeclarations[1]))))));
}
TEST_F(ProjectStorage, SynchronizeTypesChangesFunctionDeclarationReturnType)
{
- Storage::Types types{createTypes()};
- storage.synchronize(
- modules,
- imports,
- types,
- {sourceId1, sourceId2, qmlModuleSourceId, qtQuickModuleSourceId, pathToModuleSourceId},
- {});
- types[0].functionDeclarations[1].returnTypeName = "item";
+ auto package{createSimpleSynchronizationPackage()};
+ storage.synchronize(package);
+ package.types[0].functionDeclarations[1].returnTypeName = "item";
- storage.synchronize({}, importsSourceId1, {types[0]}, {sourceId1}, {});
+ storage.synchronize(SynchronizationPackage{importsSourceId1, {package.types[0]}, {sourceId1}});
ASSERT_THAT(storage.fetchTypes(),
- Contains(AllOf(IsStorageType(qtQuickModuleId,
- "QQuickItem",
- Storage::NativeType{"QObject"},
- TypeAccessSemantics::Reference,
- sourceId1),
- Field(&Storage::Type::functionDeclarations,
- UnorderedElementsAre(Eq(types[0].functionDeclarations[0]),
- Eq(types[0].functionDeclarations[1]))))));
+ Contains(
+ AllOf(IsStorageType(sourceId1,
+ "QQuickItem",
+ fetchTypeId(sourceId2, "QObject"),
+ TypeAccessSemantics::Reference),
+ Field(&Storage::Type::functionDeclarations,
+ UnorderedElementsAre(Eq(package.types[0].functionDeclarations[0]),
+ Eq(package.types[0].functionDeclarations[1]))))));
}
TEST_F(ProjectStorage, SynchronizeTypesChangesFunctionDeclarationName)
{
- Storage::Types types{createTypes()};
- storage.synchronize(
- modules,
- imports,
- types,
- {sourceId1, sourceId2, qmlModuleSourceId, qtQuickModuleSourceId, pathToModuleSourceId},
- {});
- types[0].functionDeclarations[1].name = "name";
+ auto package{createSimpleSynchronizationPackage()};
+ storage.synchronize(package);
+ package.types[0].functionDeclarations[1].name = "name";
- storage.synchronize({}, importsSourceId1, {types[0]}, {sourceId1}, {});
+ storage.synchronize(SynchronizationPackage{importsSourceId1, {package.types[0]}, {sourceId1}});
ASSERT_THAT(storage.fetchTypes(),
- Contains(AllOf(IsStorageType(qtQuickModuleId,
- "QQuickItem",
- Storage::NativeType{"QObject"},
- TypeAccessSemantics::Reference,
- sourceId1),
- Field(&Storage::Type::functionDeclarations,
- UnorderedElementsAre(Eq(types[0].functionDeclarations[0]),
- Eq(types[0].functionDeclarations[1]))))));
+ Contains(
+ AllOf(IsStorageType(sourceId1,
+ "QQuickItem",
+ fetchTypeId(sourceId2, "QObject"),
+ TypeAccessSemantics::Reference),
+ Field(&Storage::Type::functionDeclarations,
+ UnorderedElementsAre(Eq(package.types[0].functionDeclarations[0]),
+ Eq(package.types[0].functionDeclarations[1]))))));
}
TEST_F(ProjectStorage, SynchronizeTypesChangesFunctionDeclarationPopParameters)
{
- Storage::Types types{createTypes()};
- storage.synchronize(
- modules,
- imports,
- types,
- {sourceId1, sourceId2, qmlModuleSourceId, qtQuickModuleSourceId, pathToModuleSourceId},
- {});
- types[0].functionDeclarations[1].parameters.pop_back();
+ auto package{createSimpleSynchronizationPackage()};
+ storage.synchronize(package);
+ package.types[0].functionDeclarations[1].parameters.pop_back();
- storage.synchronize({}, importsSourceId1, {types[0]}, {sourceId1}, {});
+ storage.synchronize(SynchronizationPackage{importsSourceId1, {package.types[0]}, {sourceId1}});
ASSERT_THAT(storage.fetchTypes(),
- Contains(AllOf(IsStorageType(qtQuickModuleId,
- "QQuickItem",
- Storage::NativeType{"QObject"},
- TypeAccessSemantics::Reference,
- sourceId1),
- Field(&Storage::Type::functionDeclarations,
- UnorderedElementsAre(Eq(types[0].functionDeclarations[0]),
- Eq(types[0].functionDeclarations[1]))))));
+ Contains(
+ AllOf(IsStorageType(sourceId1,
+ "QQuickItem",
+ fetchTypeId(sourceId2, "QObject"),
+ TypeAccessSemantics::Reference),
+ Field(&Storage::Type::functionDeclarations,
+ UnorderedElementsAre(Eq(package.types[0].functionDeclarations[0]),
+ Eq(package.types[0].functionDeclarations[1]))))));
}
TEST_F(ProjectStorage, SynchronizeTypesChangesFunctionDeclarationAppendParameters)
{
- Storage::Types types{createTypes()};
- storage.synchronize(
- modules,
- imports,
- types,
- {sourceId1, sourceId2, qmlModuleSourceId, qtQuickModuleSourceId, pathToModuleSourceId},
- {});
- types[0].functionDeclarations[1].parameters.push_back(Storage::ParameterDeclaration{"arg4", "int"});
+ auto package{createSimpleSynchronizationPackage()};
+ storage.synchronize(package);
+ package.types[0].functionDeclarations[1].parameters.push_back(
+ Storage::ParameterDeclaration{"arg4", "int"});
- storage.synchronize({}, importsSourceId1, {types[0]}, {sourceId1}, {});
+ storage.synchronize(SynchronizationPackage{importsSourceId1, {package.types[0]}, {sourceId1}});
ASSERT_THAT(storage.fetchTypes(),
- Contains(AllOf(IsStorageType(qtQuickModuleId,
- "QQuickItem",
- Storage::NativeType{"QObject"},
- TypeAccessSemantics::Reference,
- sourceId1),
- Field(&Storage::Type::functionDeclarations,
- UnorderedElementsAre(Eq(types[0].functionDeclarations[0]),
- Eq(types[0].functionDeclarations[1]))))));
+ Contains(
+ AllOf(IsStorageType(sourceId1,
+ "QQuickItem",
+ fetchTypeId(sourceId2, "QObject"),
+ TypeAccessSemantics::Reference),
+ Field(&Storage::Type::functionDeclarations,
+ UnorderedElementsAre(Eq(package.types[0].functionDeclarations[0]),
+ Eq(package.types[0].functionDeclarations[1]))))));
}
TEST_F(ProjectStorage, SynchronizeTypesChangesFunctionDeclarationChangeParameterName)
{
- Storage::Types types{createTypes()};
- storage.synchronize(
- modules,
- imports,
- types,
- {sourceId1, sourceId2, qmlModuleSourceId, qtQuickModuleSourceId, pathToModuleSourceId},
- {});
- types[0].functionDeclarations[1].parameters[0].name = "other";
+ auto package{createSimpleSynchronizationPackage()};
+ storage.synchronize(package);
+ package.types[0].functionDeclarations[1].parameters[0].name = "other";
- storage.synchronize({}, importsSourceId1, {types[0]}, {sourceId1}, {});
+ storage.synchronize(SynchronizationPackage{importsSourceId1, {package.types[0]}, {sourceId1}});
ASSERT_THAT(storage.fetchTypes(),
- Contains(AllOf(IsStorageType(qtQuickModuleId,
- "QQuickItem",
- Storage::NativeType{"QObject"},
- TypeAccessSemantics::Reference,
- sourceId1),
- Field(&Storage::Type::functionDeclarations,
- UnorderedElementsAre(Eq(types[0].functionDeclarations[0]),
- Eq(types[0].functionDeclarations[1]))))));
+ Contains(
+ AllOf(IsStorageType(sourceId1,
+ "QQuickItem",
+ fetchTypeId(sourceId2, "QObject"),
+ TypeAccessSemantics::Reference),
+ Field(&Storage::Type::functionDeclarations,
+ UnorderedElementsAre(Eq(package.types[0].functionDeclarations[0]),
+ Eq(package.types[0].functionDeclarations[1]))))));
}
TEST_F(ProjectStorage, SynchronizeTypesChangesFunctionDeclarationChangeParameterTypeName)
{
- Storage::Types types{createTypes()};
- storage.synchronize(
- modules,
- imports,
- types,
- {sourceId1, sourceId2, qmlModuleSourceId, qtQuickModuleSourceId, pathToModuleSourceId},
- {});
- types[0].functionDeclarations[1].parameters[0].name = "long long";
+ auto package{createSimpleSynchronizationPackage()};
+ storage.synchronize(package);
+ package.types[0].functionDeclarations[1].parameters[0].name = "long long";
- storage.synchronize({}, importsSourceId1, {types[0]}, {sourceId1}, {});
+ storage.synchronize(SynchronizationPackage{importsSourceId1, {package.types[0]}, {sourceId1}});
ASSERT_THAT(storage.fetchTypes(),
- Contains(AllOf(IsStorageType(qtQuickModuleId,
- "QQuickItem",
- Storage::NativeType{"QObject"},
- TypeAccessSemantics::Reference,
- sourceId1),
- Field(&Storage::Type::functionDeclarations,
- UnorderedElementsAre(Eq(types[0].functionDeclarations[0]),
- Eq(types[0].functionDeclarations[1]))))));
+ Contains(
+ AllOf(IsStorageType(sourceId1,
+ "QQuickItem",
+ fetchTypeId(sourceId2, "QObject"),
+ TypeAccessSemantics::Reference),
+ Field(&Storage::Type::functionDeclarations,
+ UnorderedElementsAre(Eq(package.types[0].functionDeclarations[0]),
+ Eq(package.types[0].functionDeclarations[1]))))));
}
TEST_F(ProjectStorage, SynchronizeTypesChangesFunctionDeclarationChangeParameterTraits)
{
- Storage::Types types{createTypes()};
- storage.synchronize(
- modules,
- imports,
- types,
- {sourceId1, sourceId2, qmlModuleSourceId, qtQuickModuleSourceId, pathToModuleSourceId},
- {});
- types[0].functionDeclarations[1].parameters[0].traits = QmlDesigner::Storage::PropertyDeclarationTraits::IsList;
+ auto package{createSimpleSynchronizationPackage()};
+ storage.synchronize(package);
+ package.types[0].functionDeclarations[1].parameters[0].traits = QmlDesigner::Storage::
+ PropertyDeclarationTraits::IsList;
- storage.synchronize({}, importsSourceId1, {types[0]}, {sourceId1}, {});
+ storage.synchronize(SynchronizationPackage{importsSourceId1, {package.types[0]}, {sourceId1}});
ASSERT_THAT(storage.fetchTypes(),
- Contains(AllOf(IsStorageType(qtQuickModuleId,
- "QQuickItem",
- Storage::NativeType{"QObject"},
- TypeAccessSemantics::Reference,
- sourceId1),
- Field(&Storage::Type::functionDeclarations,
- UnorderedElementsAre(Eq(types[0].functionDeclarations[0]),
- Eq(types[0].functionDeclarations[1]))))));
+ Contains(
+ AllOf(IsStorageType(sourceId1,
+ "QQuickItem",
+ fetchTypeId(sourceId2, "QObject"),
+ TypeAccessSemantics::Reference),
+ Field(&Storage::Type::functionDeclarations,
+ UnorderedElementsAre(Eq(package.types[0].functionDeclarations[0]),
+ Eq(package.types[0].functionDeclarations[1]))))));
}
TEST_F(ProjectStorage, SynchronizeTypesRemovesFunctionDeclaration)
{
- Storage::Types types{createTypes()};
- storage.synchronize(
- modules,
- imports,
- types,
- {sourceId1, sourceId2, qmlModuleSourceId, qtQuickModuleSourceId, pathToModuleSourceId},
- {});
- types[0].functionDeclarations.pop_back();
+ auto package{createSimpleSynchronizationPackage()};
+ storage.synchronize(package);
+ package.types[0].functionDeclarations.pop_back();
- storage.synchronize({}, importsSourceId1, {types[0]}, {sourceId1}, {});
+ storage.synchronize(SynchronizationPackage{importsSourceId1, {package.types[0]}, {sourceId1}});
ASSERT_THAT(storage.fetchTypes(),
- Contains(AllOf(IsStorageType(qtQuickModuleId,
- "QQuickItem",
- Storage::NativeType{"QObject"},
- TypeAccessSemantics::Reference,
- sourceId1),
- Field(&Storage::Type::functionDeclarations,
- UnorderedElementsAre(Eq(types[0].functionDeclarations[0]))))));
+ Contains(
+ AllOf(IsStorageType(sourceId1,
+ "QQuickItem",
+ fetchTypeId(sourceId2, "QObject"),
+ TypeAccessSemantics::Reference),
+ Field(&Storage::Type::functionDeclarations,
+ UnorderedElementsAre(Eq(package.types[0].functionDeclarations[0]))))));
}
TEST_F(ProjectStorage, SynchronizeTypesAddFunctionDeclaration)
{
- Storage::Types types{createTypes()};
- storage.synchronize(
- modules,
- imports,
- types,
- {sourceId1, sourceId2, qmlModuleSourceId, qtQuickModuleSourceId, pathToModuleSourceId},
- {});
- types[0].functionDeclarations.push_back(
+ auto package{createSimpleSynchronizationPackage()};
+ storage.synchronize(package);
+ package.types[0].functionDeclarations.push_back(
Storage::FunctionDeclaration{"name", "string", {Storage::ParameterDeclaration{"arg", "int"}}});
- storage.synchronize({}, importsSourceId1, {types[0]}, {sourceId1}, {});
+ storage.synchronize(SynchronizationPackage{importsSourceId1, {package.types[0]}, {sourceId1}});
ASSERT_THAT(storage.fetchTypes(),
- Contains(AllOf(IsStorageType(qtQuickModuleId,
- "QQuickItem",
- Storage::NativeType{"QObject"},
- TypeAccessSemantics::Reference,
- sourceId1),
- Field(&Storage::Type::functionDeclarations,
- UnorderedElementsAre(Eq(types[0].functionDeclarations[0]),
- Eq(types[0].functionDeclarations[1]),
- Eq(types[0].functionDeclarations[2]))))));
+ Contains(
+ AllOf(IsStorageType(sourceId1,
+ "QQuickItem",
+ fetchTypeId(sourceId2, "QObject"),
+ TypeAccessSemantics::Reference),
+ Field(&Storage::Type::functionDeclarations,
+ UnorderedElementsAre(Eq(package.types[0].functionDeclarations[0]),
+ Eq(package.types[0].functionDeclarations[1]),
+ Eq(package.types[0].functionDeclarations[2]))))));
}
TEST_F(ProjectStorage, SynchronizeTypesAddSignalDeclarations)
{
- Storage::Types types{createTypes()};
+ auto package{createSimpleSynchronizationPackage()};
- storage.synchronize(
- modules,
- imports,
- types,
- {sourceId1, sourceId2, qmlModuleSourceId, qtQuickModuleSourceId, pathToModuleSourceId},
- {});
+ storage.synchronize(package);
ASSERT_THAT(storage.fetchTypes(),
- Contains(AllOf(IsStorageType(qtQuickModuleId,
- "QQuickItem",
- Storage::NativeType{"QObject"},
- TypeAccessSemantics::Reference,
- sourceId1),
- Field(&Storage::Type::signalDeclarations,
- UnorderedElementsAre(Eq(types[0].signalDeclarations[0]),
- Eq(types[0].signalDeclarations[1]))))));
+ Contains(
+ AllOf(IsStorageType(sourceId1,
+ "QQuickItem",
+ fetchTypeId(sourceId2, "QObject"),
+ TypeAccessSemantics::Reference),
+ Field(&Storage::Type::signalDeclarations,
+ UnorderedElementsAre(Eq(package.types[0].signalDeclarations[0]),
+ Eq(package.types[0].signalDeclarations[1]))))));
}
TEST_F(ProjectStorage, SynchronizeTypesChangesSignalDeclarationName)
{
- Storage::Types types{createTypes()};
- storage.synchronize(
- modules,
- imports,
- types,
- {sourceId1, sourceId2, qmlModuleSourceId, qtQuickModuleSourceId, pathToModuleSourceId},
- {});
- types[0].signalDeclarations[1].name = "name";
+ auto package{createSimpleSynchronizationPackage()};
+ storage.synchronize(package);
+ package.types[0].signalDeclarations[1].name = "name";
- storage.synchronize({}, importsSourceId1, {types[0]}, {sourceId1}, {});
+ storage.synchronize(SynchronizationPackage{importsSourceId1, {package.types[0]}, {sourceId1}});
ASSERT_THAT(storage.fetchTypes(),
- Contains(AllOf(IsStorageType(qtQuickModuleId,
- "QQuickItem",
- Storage::NativeType{"QObject"},
- TypeAccessSemantics::Reference,
- sourceId1),
- Field(&Storage::Type::signalDeclarations,
- UnorderedElementsAre(Eq(types[0].signalDeclarations[0]),
- Eq(types[0].signalDeclarations[1]))))));
+ Contains(
+ AllOf(IsStorageType(sourceId1,
+ "QQuickItem",
+ fetchTypeId(sourceId2, "QObject"),
+ TypeAccessSemantics::Reference),
+ Field(&Storage::Type::signalDeclarations,
+ UnorderedElementsAre(Eq(package.types[0].signalDeclarations[0]),
+ Eq(package.types[0].signalDeclarations[1]))))));
}
TEST_F(ProjectStorage, SynchronizeTypesChangesSignalDeclarationPopParameters)
{
- Storage::Types types{createTypes()};
- storage.synchronize(
- modules,
- imports,
- types,
- {sourceId1, sourceId2, qmlModuleSourceId, qtQuickModuleSourceId, pathToModuleSourceId},
- {});
- types[0].signalDeclarations[1].parameters.pop_back();
+ auto package{createSimpleSynchronizationPackage()};
+ storage.synchronize(package);
+ package.types[0].signalDeclarations[1].parameters.pop_back();
- storage.synchronize({}, importsSourceId1, {types[0]}, {sourceId1}, {});
+ storage.synchronize(SynchronizationPackage{importsSourceId1, {package.types[0]}, {sourceId1}});
ASSERT_THAT(storage.fetchTypes(),
- Contains(AllOf(IsStorageType(qtQuickModuleId,
- "QQuickItem",
- Storage::NativeType{"QObject"},
- TypeAccessSemantics::Reference,
- sourceId1),
- Field(&Storage::Type::signalDeclarations,
- UnorderedElementsAre(Eq(types[0].signalDeclarations[0]),
- Eq(types[0].signalDeclarations[1]))))));
+ Contains(
+ AllOf(IsStorageType(sourceId1,
+ "QQuickItem",
+ fetchTypeId(sourceId2, "QObject"),
+ TypeAccessSemantics::Reference),
+ Field(&Storage::Type::signalDeclarations,
+ UnorderedElementsAre(Eq(package.types[0].signalDeclarations[0]),
+ Eq(package.types[0].signalDeclarations[1]))))));
}
TEST_F(ProjectStorage, SynchronizeTypesChangesSignalDeclarationAppendParameters)
{
- Storage::Types types{createTypes()};
- storage.synchronize(
- modules,
- imports,
- types,
- {sourceId1, sourceId2, qmlModuleSourceId, qtQuickModuleSourceId, pathToModuleSourceId},
- {});
- types[0].signalDeclarations[1].parameters.push_back(Storage::ParameterDeclaration{"arg4", "int"});
+ auto package{createSimpleSynchronizationPackage()};
+ storage.synchronize(package);
+ package.types[0].signalDeclarations[1].parameters.push_back(
+ Storage::ParameterDeclaration{"arg4", "int"});
- storage.synchronize({}, importsSourceId1, {types[0]}, {sourceId1}, {});
+ storage.synchronize(SynchronizationPackage{importsSourceId1, {package.types[0]}, {sourceId1}});
ASSERT_THAT(storage.fetchTypes(),
- Contains(AllOf(IsStorageType(qtQuickModuleId,
- "QQuickItem",
- Storage::NativeType{"QObject"},
- TypeAccessSemantics::Reference,
- sourceId1),
- Field(&Storage::Type::signalDeclarations,
- UnorderedElementsAre(Eq(types[0].signalDeclarations[0]),
- Eq(types[0].signalDeclarations[1]))))));
+ Contains(
+ AllOf(IsStorageType(sourceId1,
+ "QQuickItem",
+ fetchTypeId(sourceId2, "QObject"),
+ TypeAccessSemantics::Reference),
+ Field(&Storage::Type::signalDeclarations,
+ UnorderedElementsAre(Eq(package.types[0].signalDeclarations[0]),
+ Eq(package.types[0].signalDeclarations[1]))))));
}
TEST_F(ProjectStorage, SynchronizeTypesChangesSignalDeclarationChangeParameterName)
{
- Storage::Types types{createTypes()};
- storage.synchronize(
- modules,
- imports,
- types,
- {sourceId1, sourceId2, qmlModuleSourceId, qtQuickModuleSourceId, pathToModuleSourceId},
- {});
- types[0].signalDeclarations[1].parameters[0].name = "other";
+ auto package{createSimpleSynchronizationPackage()};
+ storage.synchronize(package);
+ package.types[0].signalDeclarations[1].parameters[0].name = "other";
- storage.synchronize({}, importsSourceId1, {types[0]}, {sourceId1}, {});
+ storage.synchronize(SynchronizationPackage{importsSourceId1, {package.types[0]}, {sourceId1}});
ASSERT_THAT(storage.fetchTypes(),
- Contains(AllOf(IsStorageType(qtQuickModuleId,
- "QQuickItem",
- Storage::NativeType{"QObject"},
- TypeAccessSemantics::Reference,
- sourceId1),
- Field(&Storage::Type::signalDeclarations,
- UnorderedElementsAre(Eq(types[0].signalDeclarations[0]),
- Eq(types[0].signalDeclarations[1]))))));
+ Contains(
+ AllOf(IsStorageType(sourceId1,
+ "QQuickItem",
+ fetchTypeId(sourceId2, "QObject"),
+ TypeAccessSemantics::Reference),
+ Field(&Storage::Type::signalDeclarations,
+ UnorderedElementsAre(Eq(package.types[0].signalDeclarations[0]),
+ Eq(package.types[0].signalDeclarations[1]))))));
}
TEST_F(ProjectStorage, SynchronizeTypesChangesSignalDeclarationChangeParameterTypeName)
{
- Storage::Types types{createTypes()};
- storage.synchronize(
- modules,
- imports,
- types,
- {sourceId1, sourceId2, qmlModuleSourceId, qtQuickModuleSourceId, pathToModuleSourceId},
- {});
- types[0].signalDeclarations[1].parameters[0].typeName = "long long";
+ auto package{createSimpleSynchronizationPackage()};
+ storage.synchronize(package);
+ package.types[0].signalDeclarations[1].parameters[0].typeName = "long long";
- storage.synchronize({}, importsSourceId1, {types[0]}, {sourceId1}, {});
+ storage.synchronize(SynchronizationPackage{importsSourceId1, {package.types[0]}, {sourceId1}});
ASSERT_THAT(storage.fetchTypes(),
- Contains(AllOf(IsStorageType(qtQuickModuleId,
- "QQuickItem",
- Storage::NativeType{"QObject"},
- TypeAccessSemantics::Reference,
- sourceId1),
- Field(&Storage::Type::signalDeclarations,
- UnorderedElementsAre(Eq(types[0].signalDeclarations[0]),
- Eq(types[0].signalDeclarations[1]))))));
+ Contains(
+ AllOf(IsStorageType(sourceId1,
+ "QQuickItem",
+ fetchTypeId(sourceId2, "QObject"),
+ TypeAccessSemantics::Reference),
+ Field(&Storage::Type::signalDeclarations,
+ UnorderedElementsAre(Eq(package.types[0].signalDeclarations[0]),
+ Eq(package.types[0].signalDeclarations[1]))))));
}
TEST_F(ProjectStorage, SynchronizeTypesChangesSignalDeclarationChangeParameterTraits)
{
- Storage::Types types{createTypes()};
- storage.synchronize(
- modules,
- imports,
- types,
- {sourceId1, sourceId2, qmlModuleSourceId, qtQuickModuleSourceId, pathToModuleSourceId},
- {});
- types[0].signalDeclarations[1].parameters[0].traits = QmlDesigner::Storage::PropertyDeclarationTraits::IsList;
+ auto package{createSimpleSynchronizationPackage()};
+ storage.synchronize(package);
+ package.types[0].signalDeclarations[1].parameters[0].traits = QmlDesigner::Storage::PropertyDeclarationTraits::IsList;
- storage.synchronize({}, importsSourceId1, {types[0]}, {sourceId1}, {});
+ storage.synchronize(SynchronizationPackage{importsSourceId1, {package.types[0]}, {sourceId1}});
ASSERT_THAT(storage.fetchTypes(),
- Contains(AllOf(IsStorageType(qtQuickModuleId,
- "QQuickItem",
- Storage::NativeType{"QObject"},
- TypeAccessSemantics::Reference,
- sourceId1),
- Field(&Storage::Type::signalDeclarations,
- UnorderedElementsAre(Eq(types[0].signalDeclarations[0]),
- Eq(types[0].signalDeclarations[1]))))));
+ Contains(
+ AllOf(IsStorageType(sourceId1,
+ "QQuickItem",
+ fetchTypeId(sourceId2, "QObject"),
+ TypeAccessSemantics::Reference),
+ Field(&Storage::Type::signalDeclarations,
+ UnorderedElementsAre(Eq(package.types[0].signalDeclarations[0]),
+ Eq(package.types[0].signalDeclarations[1]))))));
}
TEST_F(ProjectStorage, SynchronizeTypesRemovesSignalDeclaration)
{
- Storage::Types types{createTypes()};
- storage.synchronize(
- modules,
- imports,
- types,
- {sourceId1, sourceId2, qmlModuleSourceId, qtQuickModuleSourceId, pathToModuleSourceId},
- {});
- types[0].signalDeclarations.pop_back();
+ auto package{createSimpleSynchronizationPackage()};
+ storage.synchronize(package);
+ package.types[0].signalDeclarations.pop_back();
- storage.synchronize({}, importsSourceId1, {types[0]}, {sourceId1}, {});
+ storage.synchronize(SynchronizationPackage{importsSourceId1, {package.types[0]}, {sourceId1}});
ASSERT_THAT(storage.fetchTypes(),
- Contains(AllOf(IsStorageType(qtQuickModuleId,
- "QQuickItem",
- Storage::NativeType{"QObject"},
- TypeAccessSemantics::Reference,
- sourceId1),
- Field(&Storage::Type::signalDeclarations,
- UnorderedElementsAre(Eq(types[0].signalDeclarations[0]))))));
+ Contains(
+ AllOf(IsStorageType(sourceId1,
+ "QQuickItem",
+ fetchTypeId(sourceId2, "QObject"),
+ TypeAccessSemantics::Reference),
+ Field(&Storage::Type::signalDeclarations,
+ UnorderedElementsAre(Eq(package.types[0].signalDeclarations[0]))))));
}
TEST_F(ProjectStorage, SynchronizeTypesAddSignalDeclaration)
{
- Storage::Types types{createTypes()};
- storage.synchronize(
- modules,
- imports,
- types,
- {sourceId1, sourceId2, qmlModuleSourceId, qtQuickModuleSourceId, pathToModuleSourceId},
- {});
- types[0].signalDeclarations.push_back(
+ auto package{createSimpleSynchronizationPackage()};
+ storage.synchronize(package);
+ package.types[0].signalDeclarations.push_back(
Storage::SignalDeclaration{"name", {Storage::ParameterDeclaration{"arg", "int"}}});
- storage.synchronize({}, importsSourceId1, {types[0]}, {sourceId1}, {});
+ storage.synchronize(SynchronizationPackage{importsSourceId1, {package.types[0]}, {sourceId1}});
ASSERT_THAT(storage.fetchTypes(),
- Contains(AllOf(IsStorageType(qtQuickModuleId,
- "QQuickItem",
- Storage::NativeType{"QObject"},
- TypeAccessSemantics::Reference,
- sourceId1),
- Field(&Storage::Type::signalDeclarations,
- UnorderedElementsAre(Eq(types[0].signalDeclarations[0]),
- Eq(types[0].signalDeclarations[1]),
- Eq(types[0].signalDeclarations[2]))))));
+ Contains(
+ AllOf(IsStorageType(sourceId1,
+ "QQuickItem",
+ fetchTypeId(sourceId2, "QObject"),
+ TypeAccessSemantics::Reference),
+ Field(&Storage::Type::signalDeclarations,
+ UnorderedElementsAre(Eq(package.types[0].signalDeclarations[0]),
+ Eq(package.types[0].signalDeclarations[1]),
+ Eq(package.types[0].signalDeclarations[2]))))));
}
TEST_F(ProjectStorage, SynchronizeTypesAddEnumerationDeclarations)
{
- Storage::Types types{createTypes()};
+ auto package{createSimpleSynchronizationPackage()};
- storage.synchronize(
- modules,
- imports,
- types,
- {sourceId1, sourceId2, qmlModuleSourceId, qtQuickModuleSourceId, pathToModuleSourceId},
- {});
+ storage.synchronize(package);
ASSERT_THAT(storage.fetchTypes(),
- Contains(AllOf(IsStorageType(qtQuickModuleId,
- "QQuickItem",
- Storage::NativeType{"QObject"},
- TypeAccessSemantics::Reference,
- sourceId1),
- Field(&Storage::Type::enumerationDeclarations,
- UnorderedElementsAre(Eq(types[0].enumerationDeclarations[0]),
- Eq(types[0].enumerationDeclarations[1]))))));
+ Contains(AllOf(
+ IsStorageType(sourceId1,
+ "QQuickItem",
+ fetchTypeId(sourceId2, "QObject"),
+ TypeAccessSemantics::Reference),
+ Field(&Storage::Type::enumerationDeclarations,
+ UnorderedElementsAre(Eq(package.types[0].enumerationDeclarations[0]),
+ Eq(package.types[0].enumerationDeclarations[1]))))));
}
TEST_F(ProjectStorage, SynchronizeTypesChangesEnumerationDeclarationName)
{
- Storage::Types types{createTypes()};
- storage.synchronize(
- modules,
- imports,
- types,
- {sourceId1, sourceId2, qmlModuleSourceId, qtQuickModuleSourceId, pathToModuleSourceId},
- {});
- types[0].enumerationDeclarations[1].name = "Name";
+ auto package{createSimpleSynchronizationPackage()};
+ storage.synchronize(package);
+ package.types[0].enumerationDeclarations[1].name = "Name";
- storage.synchronize({}, importsSourceId1, {types[0]}, {sourceId1}, {});
+ storage.synchronize(SynchronizationPackage{importsSourceId1, {package.types[0]}, {sourceId1}});
ASSERT_THAT(storage.fetchTypes(),
- Contains(AllOf(IsStorageType(qtQuickModuleId,
- "QQuickItem",
- Storage::NativeType{"QObject"},
- TypeAccessSemantics::Reference,
- sourceId1),
- Field(&Storage::Type::enumerationDeclarations,
- UnorderedElementsAre(Eq(types[0].enumerationDeclarations[0]),
- Eq(types[0].enumerationDeclarations[1]))))));
+ Contains(AllOf(
+ IsStorageType(sourceId1,
+ "QQuickItem",
+ fetchTypeId(sourceId2, "QObject"),
+ TypeAccessSemantics::Reference),
+ Field(&Storage::Type::enumerationDeclarations,
+ UnorderedElementsAre(Eq(package.types[0].enumerationDeclarations[0]),
+ Eq(package.types[0].enumerationDeclarations[1]))))));
}
TEST_F(ProjectStorage, SynchronizeTypesChangesEnumerationDeclarationPopEnumeratorDeclaration)
{
- Storage::Types types{createTypes()};
- storage.synchronize(
- modules,
- imports,
- types,
- {sourceId1, sourceId2, qmlModuleSourceId, qtQuickModuleSourceId, pathToModuleSourceId},
- {});
- types[0].enumerationDeclarations[1].enumeratorDeclarations.pop_back();
+ auto package{createSimpleSynchronizationPackage()};
+ storage.synchronize(package);
+ package.types[0].enumerationDeclarations[1].enumeratorDeclarations.pop_back();
- storage.synchronize({}, importsSourceId1, {types[0]}, {sourceId1}, {});
+ storage.synchronize(SynchronizationPackage{importsSourceId1, {package.types[0]}, {sourceId1}});
ASSERT_THAT(storage.fetchTypes(),
- Contains(AllOf(IsStorageType(qtQuickModuleId,
- "QQuickItem",
- Storage::NativeType{"QObject"},
- TypeAccessSemantics::Reference,
- sourceId1),
- Field(&Storage::Type::enumerationDeclarations,
- UnorderedElementsAre(Eq(types[0].enumerationDeclarations[0]),
- Eq(types[0].enumerationDeclarations[1]))))));
+ Contains(AllOf(
+ IsStorageType(sourceId1,
+ "QQuickItem",
+ fetchTypeId(sourceId2, "QObject"),
+ TypeAccessSemantics::Reference),
+ Field(&Storage::Type::enumerationDeclarations,
+ UnorderedElementsAre(Eq(package.types[0].enumerationDeclarations[0]),
+ Eq(package.types[0].enumerationDeclarations[1]))))));
}
TEST_F(ProjectStorage, SynchronizeTypesChangesEnumerationDeclarationAppendEnumeratorDeclaration)
{
- Storage::Types types{createTypes()};
- storage.synchronize(
- modules,
- imports,
- types,
- {sourceId1, sourceId2, qmlModuleSourceId, qtQuickModuleSourceId, pathToModuleSourceId},
- {});
- types[0].enumerationDeclarations[1].enumeratorDeclarations.push_back(
+ auto package{createSimpleSynchronizationPackage()};
+ storage.synchronize(package);
+ package.types[0].enumerationDeclarations[1].enumeratorDeclarations.push_back(
Storage::EnumeratorDeclaration{"Haa", 54});
- storage.synchronize({}, importsSourceId1, {types[0]}, {sourceId1}, {});
+ storage.synchronize(SynchronizationPackage{importsSourceId1, {package.types[0]}, {sourceId1}});
ASSERT_THAT(storage.fetchTypes(),
- Contains(AllOf(IsStorageType(qtQuickModuleId,
- "QQuickItem",
- Storage::NativeType{"QObject"},
- TypeAccessSemantics::Reference,
- sourceId1),
- Field(&Storage::Type::enumerationDeclarations,
- UnorderedElementsAre(Eq(types[0].enumerationDeclarations[0]),
- Eq(types[0].enumerationDeclarations[1]))))));
+ Contains(AllOf(
+ IsStorageType(sourceId1,
+ "QQuickItem",
+ fetchTypeId(sourceId2, "QObject"),
+ TypeAccessSemantics::Reference),
+ Field(&Storage::Type::enumerationDeclarations,
+ UnorderedElementsAre(Eq(package.types[0].enumerationDeclarations[0]),
+ Eq(package.types[0].enumerationDeclarations[1]))))));
}
TEST_F(ProjectStorage, SynchronizeTypesChangesEnumerationDeclarationChangeEnumeratorDeclarationName)
{
- Storage::Types types{createTypes()};
- storage.synchronize(
- modules,
- imports,
- types,
- {sourceId1, sourceId2, qmlModuleSourceId, qtQuickModuleSourceId, pathToModuleSourceId},
- {});
- types[0].enumerationDeclarations[1].enumeratorDeclarations[0].name = "Hoo";
+ auto package{createSimpleSynchronizationPackage()};
+ storage.synchronize(package);
+ package.types[0].enumerationDeclarations[1].enumeratorDeclarations[0].name = "Hoo";
- storage.synchronize({}, importsSourceId1, {types[0]}, {sourceId1}, {});
+ storage.synchronize(SynchronizationPackage{importsSourceId1, {package.types[0]}, {sourceId1}});
ASSERT_THAT(storage.fetchTypes(),
- Contains(AllOf(IsStorageType(qtQuickModuleId,
- "QQuickItem",
- Storage::NativeType{"QObject"},
- TypeAccessSemantics::Reference,
- sourceId1),
- Field(&Storage::Type::enumerationDeclarations,
- UnorderedElementsAre(Eq(types[0].enumerationDeclarations[0]),
- Eq(types[0].enumerationDeclarations[1]))))));
+ Contains(AllOf(
+ IsStorageType(sourceId1,
+ "QQuickItem",
+ fetchTypeId(sourceId2, "QObject"),
+ TypeAccessSemantics::Reference),
+ Field(&Storage::Type::enumerationDeclarations,
+ UnorderedElementsAre(Eq(package.types[0].enumerationDeclarations[0]),
+ Eq(package.types[0].enumerationDeclarations[1]))))));
}
TEST_F(ProjectStorage, SynchronizeTypesChangesEnumerationDeclarationChangeEnumeratorDeclarationValue)
{
- Storage::Types types{createTypes()};
- storage.synchronize(
- modules,
- imports,
- types,
- {sourceId1, sourceId2, qmlModuleSourceId, qtQuickModuleSourceId, pathToModuleSourceId},
- {});
- types[0].enumerationDeclarations[1].enumeratorDeclarations[1].value = 11;
+ auto package{createSimpleSynchronizationPackage()};
+ storage.synchronize(package);
+ package.types[0].enumerationDeclarations[1].enumeratorDeclarations[1].value = 11;
- storage.synchronize({}, importsSourceId1, {types[0]}, {sourceId1}, {});
+ storage.synchronize(SynchronizationPackage{importsSourceId1, {package.types[0]}, {sourceId1}});
ASSERT_THAT(storage.fetchTypes(),
- Contains(AllOf(IsStorageType(qtQuickModuleId,
- "QQuickItem",
- Storage::NativeType{"QObject"},
- TypeAccessSemantics::Reference,
- sourceId1),
- Field(&Storage::Type::enumerationDeclarations,
- UnorderedElementsAre(Eq(types[0].enumerationDeclarations[0]),
- Eq(types[0].enumerationDeclarations[1]))))));
+ Contains(AllOf(
+ IsStorageType(sourceId1,
+ "QQuickItem",
+ fetchTypeId(sourceId2, "QObject"),
+ TypeAccessSemantics::Reference),
+ Field(&Storage::Type::enumerationDeclarations,
+ UnorderedElementsAre(Eq(package.types[0].enumerationDeclarations[0]),
+ Eq(package.types[0].enumerationDeclarations[1]))))));
}
TEST_F(ProjectStorage,
SynchronizeTypesChangesEnumerationDeclarationAddThatEnumeratorDeclarationHasValue)
{
- Storage::Types types{createTypes()};
- storage.synchronize(
- modules,
- imports,
- types,
- {sourceId1, sourceId2, qmlModuleSourceId, qtQuickModuleSourceId, pathToModuleSourceId},
- {});
- types[0].enumerationDeclarations[1].enumeratorDeclarations[0].value = 11;
- types[0].enumerationDeclarations[1].enumeratorDeclarations[0].hasValue = true;
+ auto package{createSimpleSynchronizationPackage()};
+ storage.synchronize(package);
+ package.types[0].enumerationDeclarations[1].enumeratorDeclarations[0].value = 11;
+ package.types[0].enumerationDeclarations[1].enumeratorDeclarations[0].hasValue = true;
- storage.synchronize({}, importsSourceId1, {types[0]}, {sourceId1}, {});
+ storage.synchronize(SynchronizationPackage{importsSourceId1, {package.types[0]}, {sourceId1}});
ASSERT_THAT(storage.fetchTypes(),
- Contains(AllOf(IsStorageType(qtQuickModuleId,
- "QQuickItem",
- Storage::NativeType{"QObject"},
- TypeAccessSemantics::Reference,
- sourceId1),
- Field(&Storage::Type::enumerationDeclarations,
- UnorderedElementsAre(Eq(types[0].enumerationDeclarations[0]),
- Eq(types[0].enumerationDeclarations[1]))))));
+ Contains(AllOf(
+ IsStorageType(sourceId1,
+ "QQuickItem",
+ fetchTypeId(sourceId2, "QObject"),
+ TypeAccessSemantics::Reference),
+ Field(&Storage::Type::enumerationDeclarations,
+ UnorderedElementsAre(Eq(package.types[0].enumerationDeclarations[0]),
+ Eq(package.types[0].enumerationDeclarations[1]))))));
}
TEST_F(ProjectStorage,
SynchronizeTypesChangesEnumerationDeclarationRemoveThatEnumeratorDeclarationHasValue)
{
- Storage::Types types{createTypes()};
- storage.synchronize(
- modules,
- imports,
- types,
- {sourceId1, sourceId2, qmlModuleSourceId, qtQuickModuleSourceId, pathToModuleSourceId},
- {});
- types[0].enumerationDeclarations[1].enumeratorDeclarations[0].hasValue = false;
+ auto package{createSimpleSynchronizationPackage()};
+ storage.synchronize(package);
+ package.types[0].enumerationDeclarations[1].enumeratorDeclarations[0].hasValue = false;
- storage.synchronize({}, importsSourceId1, {types[0]}, {sourceId1}, {});
+ storage.synchronize(SynchronizationPackage{importsSourceId1, {package.types[0]}, {sourceId1}});
ASSERT_THAT(storage.fetchTypes(),
- Contains(AllOf(IsStorageType(qtQuickModuleId,
- "QQuickItem",
- Storage::NativeType{"QObject"},
- TypeAccessSemantics::Reference,
- sourceId1),
- Field(&Storage::Type::enumerationDeclarations,
- UnorderedElementsAre(Eq(types[0].enumerationDeclarations[0]),
- Eq(types[0].enumerationDeclarations[1]))))));
+ Contains(AllOf(
+ IsStorageType(sourceId1,
+ "QQuickItem",
+ fetchTypeId(sourceId2, "QObject"),
+ TypeAccessSemantics::Reference),
+ Field(&Storage::Type::enumerationDeclarations,
+ UnorderedElementsAre(Eq(package.types[0].enumerationDeclarations[0]),
+ Eq(package.types[0].enumerationDeclarations[1]))))));
}
TEST_F(ProjectStorage, SynchronizeTypesRemovesEnumerationDeclaration)
{
- Storage::Types types{createTypes()};
- storage.synchronize(
- modules,
- imports,
- types,
- {sourceId1, sourceId2, qmlModuleSourceId, qtQuickModuleSourceId, pathToModuleSourceId},
- {});
- types[0].enumerationDeclarations.pop_back();
+ auto package{createSimpleSynchronizationPackage()};
+ storage.synchronize(package);
+ package.types[0].enumerationDeclarations.pop_back();
- storage.synchronize({}, importsSourceId1, {types[0]}, {sourceId1}, {});
+ storage.synchronize(SynchronizationPackage{importsSourceId1, {package.types[0]}, {sourceId1}});
ASSERT_THAT(storage.fetchTypes(),
- Contains(AllOf(IsStorageType(qtQuickModuleId,
+ Contains(AllOf(IsStorageType(sourceId1,
"QQuickItem",
- Storage::NativeType{"QObject"},
- TypeAccessSemantics::Reference,
- sourceId1),
+ fetchTypeId(sourceId2, "QObject"),
+ TypeAccessSemantics::Reference),
Field(&Storage::Type::enumerationDeclarations,
- UnorderedElementsAre(Eq(types[0].enumerationDeclarations[0]))))));
+ UnorderedElementsAre(
+ Eq(package.types[0].enumerationDeclarations[0]))))));
}
TEST_F(ProjectStorage, SynchronizeTypesAddEnumerationDeclaration)
{
- Storage::Types types{createTypes()};
- storage.synchronize(
- modules,
- imports,
- types,
- {sourceId1, sourceId2, qmlModuleSourceId, qtQuickModuleSourceId, pathToModuleSourceId},
- {});
- types[0].enumerationDeclarations.push_back(
+ auto package{createSimpleSynchronizationPackage()};
+ storage.synchronize(package);
+ package.types[0].enumerationDeclarations.push_back(
Storage::EnumerationDeclaration{"name", {Storage::EnumeratorDeclaration{"Foo", 98, true}}});
- storage.synchronize({}, importsSourceId1, {types[0]}, {sourceId1}, {});
+ storage.synchronize(SynchronizationPackage{importsSourceId1, {package.types[0]}, {sourceId1}});
ASSERT_THAT(storage.fetchTypes(),
- Contains(AllOf(IsStorageType(qtQuickModuleId,
- "QQuickItem",
- Storage::NativeType{"QObject"},
- TypeAccessSemantics::Reference,
- sourceId1),
- Field(&Storage::Type::enumerationDeclarations,
- UnorderedElementsAre(Eq(types[0].enumerationDeclarations[0]),
- Eq(types[0].enumerationDeclarations[1]),
- Eq(types[0].enumerationDeclarations[2]))))));
-}
-
-TEST_F(ProjectStorage, SynchronizeModulesAddModules)
-{
- Storage::Modules modules{createModules()};
-
- storage.synchronize(modules, {}, {}, {qmlModuleSourceId, qtQuickModuleSourceId, moduleSourceId5}, {});
-
- ASSERT_THAT(storage.fetchAllModules(),
- UnorderedElementsAre(IsModule("Qml", qmlModuleSourceId),
- IsModule("QtQuick", qtQuickModuleSourceId),
- IsModule("/path/to", pathToModuleSourceId)));
-}
-
-TEST_F(ProjectStorage, SynchronizeModulesAddModulesAgain)
-{
- Storage::Modules modules{createModules()};
- storage.synchronize(modules,
- {},
- {},
- {qmlModuleSourceId, qtQuickModuleSourceId, pathToModuleSourceId},
- {});
-
- storage.synchronize(modules,
- {},
- {},
- {qmlModuleSourceId, qtQuickModuleSourceId, pathToModuleSourceId},
- {});
-
- ASSERT_THAT(storage.fetchAllModules(),
- UnorderedElementsAre(IsModule("Qml", qmlModuleSourceId),
- IsModule("QtQuick", qtQuickModuleSourceId),
- IsModule("/path/to", pathToModuleSourceId)));
-}
-
-TEST_F(ProjectStorage, SynchronizeModulesUpdateToMoreModules)
-{
- Storage::Modules modules{createModules()};
- storage.synchronize(modules,
- {},
- {},
- {qmlModuleSourceId, qtQuickModuleSourceId, pathToModuleSourceId},
- {});
- modules.push_back(Storage::Module{"QtQuick.Foo", moduleSourceId4});
-
- storage.synchronize(modules,
- {},
- {},
- {qmlModuleSourceId, qtQuickModuleSourceId, pathToModuleSourceId, moduleSourceId4},
- {});
-
- ASSERT_THAT(storage.fetchAllModules(),
- UnorderedElementsAre(IsModule("Qml", qmlModuleSourceId),
- IsModule("QtQuick", qtQuickModuleSourceId),
- IsModule("/path/to", pathToModuleSourceId),
- IsModule("QtQuick.Foo", moduleSourceId4)));
-}
-
-TEST_F(ProjectStorage, SynchronizeModulesAddOneMoreModules)
-{
- Storage::Modules modules{createModules()};
- storage.synchronize(modules,
- {},
- {},
- {qmlModuleSourceId, qtQuickModuleSourceId, pathToModuleSourceId},
- {});
- auto newModule = Storage::Module{"QtQuick.Foo", moduleSourceId4};
-
- storage.synchronize({newModule}, {}, {}, {moduleSourceId4}, {});
-
- ASSERT_THAT(storage.fetchAllModules(),
- UnorderedElementsAre(IsModule("Qml", qmlModuleSourceId),
- IsModule("QtQuick", qtQuickModuleSourceId),
- IsModule("/path/to", pathToModuleSourceId),
- IsModule("QtQuick.Foo", moduleSourceId4)));
-}
-
-TEST_F(ProjectStorage, SynchronizeModulesRemoveModule)
-{
- Storage::Modules modules{createModules()};
- storage.synchronize(modules,
- {},
- {},
- {qmlModuleSourceId, qtQuickModuleSourceId, pathToModuleSourceId},
- {});
-
- storage.synchronize({}, {}, {}, {pathToModuleSourceId}, {});
-
- ASSERT_THAT(storage.fetchAllModules(),
- UnorderedElementsAre(IsModule("Qml", qmlModuleSourceId),
- IsModule("QtQuick", qtQuickModuleSourceId)));
-}
-
-TEST_F(ProjectStorage, SynchronizeModulesChangeSourceId)
-{
- Storage::Modules modules{createModules()};
- storage.synchronize(modules,
- {},
- {},
- {qmlModuleSourceId, qtQuickModuleSourceId, pathToModuleSourceId},
- {});
- modules[1].sourceId = moduleSourceId4;
-
- storage.synchronize({modules[1]}, {}, {}, {qtQuickModuleSourceId, moduleSourceId4}, {});
-
- ASSERT_THAT(storage.fetchAllModules(),
- UnorderedElementsAre(IsModule("Qml", qmlModuleSourceId),
- IsModule("QtQuick", moduleSourceId4),
- IsModule("/path/to", pathToModuleSourceId)));
-}
-
-TEST_F(ProjectStorage, SynchronizeModulesChangeName)
-{
- Storage::Modules modules{createModules()};
- storage.synchronize(modules,
- {},
- {},
- {qmlModuleSourceId, qtQuickModuleSourceId, pathToModuleSourceId},
- {});
- modules[0].name = "Qml2";
-
- storage.synchronize(modules,
- {},
- {},
- {qmlModuleSourceId, qtQuickModuleSourceId, pathToModuleSourceId},
- {});
-
- ASSERT_THAT(storage.fetchAllModules(),
- UnorderedElementsAre(IsModule("Qml2", qmlModuleSourceId),
- IsModule("QtQuick", qtQuickModuleSourceId),
- IsModule("/path/to", pathToModuleSourceId)));
-}
-
-TEST_F(ProjectStorage, RemovingModuleRemovesDependentTypesToo)
-{
- Storage::Types types{createTypes()};
- types[0].prototype = Storage::NativeType{""};
- types[0].propertyDeclarations.clear();
- storage.synchronize(
- modules,
- imports,
- types,
- {sourceId1, sourceId2, qmlModuleSourceId, qtQuickModuleSourceId, pathToModuleSourceId},
- {});
-
- storage.synchronize({}, {}, {}, {qtQuickModuleSourceId, pathToModuleSourceId}, {});
-
- ASSERT_THAT(storage.fetchTypes(),
- UnorderedElementsAre(IsStorageType(qmlModuleId,
- "QObject",
- Storage::NativeType{},
- TypeAccessSemantics::Reference,
- sourceId2)));
-}
-
-TEST_F(ProjectStorage, RemovingModuleThrowsForMissingType)
-{
- Storage::Types types{createTypes()};
- imports.emplace_back("QtQuick", Storage::Version{}, sourceId2);
- types[0].prototype = Storage::NativeType{""};
- types[0].propertyDeclarations.clear();
- types[1].prototype = Storage::ImportedType{"Item"};
- storage.synchronize(
- modules,
- imports,
- types,
- {sourceId1, sourceId2, qmlModuleSourceId, qtQuickModuleSourceId, pathToModuleSourceId},
- {});
-
- ASSERT_THROW(storage.synchronize({}, {}, {}, {qtQuickModuleSourceId, pathToModuleSourceId}, {}),
- QmlDesigner::TypeNameDoesNotExists);
+ Contains(AllOf(
+ IsStorageType(sourceId1,
+ "QQuickItem",
+ fetchTypeId(sourceId2, "QObject"),
+ TypeAccessSemantics::Reference),
+ Field(&Storage::Type::enumerationDeclarations,
+ UnorderedElementsAre(Eq(package.types[0].enumerationDeclarations[0]),
+ Eq(package.types[0].enumerationDeclarations[1]),
+ Eq(package.types[0].enumerationDeclarations[2]))))));
}
-TEST_F(ProjectStorage, FetchTypeIdByModuleIdAndName)
+TEST_F(ProjectStorage, FetchTypeIdBySourceIdAndName)
{
- Storage::Types types{createTypes()};
- storage.synchronize(
- modules,
- imports,
- types,
- {sourceId1, sourceId2, qmlModuleSourceId, qtQuickModuleSourceId, pathToModuleSourceId},
- {});
- auto qmlModuleId = storage.fetchModuleId("Qml");
+ auto package{createSimpleSynchronizationPackage()};
+ storage.synchronize(package);
- auto typeId = storage.fetchTypeIdByName(qmlModuleId, "QObject");
+ auto typeId = storage.fetchTypeIdByName(sourceId2, "QObject");
ASSERT_THAT(storage.fetchTypeIdByExportedName("Object"), Eq(typeId));
}
TEST_F(ProjectStorage, FetchTypeIdByExportedName)
{
- Storage::Types types{createTypes()};
- storage.synchronize(
- modules,
- imports,
- types,
- {sourceId1, sourceId2, qmlModuleSourceId, qtQuickModuleSourceId, pathToModuleSourceId},
- {});
- auto qmlModuleId = storage.fetchModuleId("Qml");
+ auto package{createSimpleSynchronizationPackage()};
+ storage.synchronize(package);
auto typeId = storage.fetchTypeIdByExportedName("Object");
- ASSERT_THAT(storage.fetchTypeIdByName(qmlModuleId, "QObject"), Eq(typeId));
+ ASSERT_THAT(storage.fetchTypeIdByName(sourceId2, "QObject"), Eq(typeId));
}
TEST_F(ProjectStorage, FetchTypeIdByImporIdsAndExportedName)
{
- Storage::Types types{createTypes()};
- storage.synchronize(
- modules,
- imports,
- types,
- {sourceId1, sourceId2, qmlModuleSourceId, qtQuickModuleSourceId, pathToModuleSourceId},
- {});
- auto qmlModuleId = storage.fetchModuleId("Qml");
- auto qtQuickModuleId = storage.fetchModuleId("QtQuick");
+ auto package{createSimpleSynchronizationPackage()};
+ storage.synchronize(package);
auto typeId = storage.fetchTypeIdByModuleIdsAndExportedName({qmlModuleId, qtQuickModuleId},
"Object");
- ASSERT_THAT(storage.fetchTypeIdByName(qmlModuleId, "QObject"), Eq(typeId));
+ ASSERT_THAT(storage.fetchTypeIdByName(sourceId2, "QObject"), Eq(typeId));
}
TEST_F(ProjectStorage, FetchInvalidTypeIdByImporIdsAndExportedNameIfModuleIdsAreEmpty)
{
- Storage::Types types{createTypes()};
- storage.synchronize(
- modules,
- imports,
- types,
- {sourceId1, sourceId2, qmlModuleSourceId, qtQuickModuleSourceId, pathToModuleSourceId},
- {});
+ auto package{createSimpleSynchronizationPackage()};
+ storage.synchronize(package);
+
auto typeId = storage.fetchTypeIdByModuleIdsAndExportedName({}, "Object");
ASSERT_FALSE(typeId.isValid());
@@ -2451,13 +1858,9 @@ TEST_F(ProjectStorage, FetchInvalidTypeIdByImporIdsAndExportedNameIfModuleIdsAre
TEST_F(ProjectStorage, FetchInvalidTypeIdByImporIdsAndExportedNameIfModuleIdsAreInvalid)
{
- Storage::Types types{createTypes()};
- storage.synchronize(
- modules,
- imports,
- types,
- {sourceId1, sourceId2, qmlModuleSourceId, qtQuickModuleSourceId, pathToModuleSourceId},
- {});
+ auto package{createSimpleSynchronizationPackage()};
+ storage.synchronize(package);
+
auto typeId = storage.fetchTypeIdByModuleIdsAndExportedName({ModuleId{}}, "Object");
ASSERT_FALSE(typeId.isValid());
@@ -2465,14 +1868,10 @@ TEST_F(ProjectStorage, FetchInvalidTypeIdByImporIdsAndExportedNameIfModuleIdsAre
TEST_F(ProjectStorage, FetchInvalidTypeIdByImporIdsAndExportedNameIfNotInModule)
{
- Storage::Types types{createTypes()};
- storage.synchronize(
- modules,
- imports,
- types,
- {sourceId1, sourceId2, qmlModuleSourceId, qtQuickModuleSourceId, pathToModuleSourceId},
- {});
- auto qtQuickModuleId = storage.fetchModuleId("QtQuick");
+ auto package{createSimpleSynchronizationPackage()};
+ storage.synchronize(package);
+ auto qtQuickModuleId = storage.moduleId("QtQuick");
+
auto typeId = storage.fetchTypeIdByModuleIdsAndExportedName({qtQuickModuleId}, "Object");
ASSERT_FALSE(typeId.isValid());
@@ -2480,1283 +1879,906 @@ TEST_F(ProjectStorage, FetchInvalidTypeIdByImporIdsAndExportedNameIfNotInModule)
TEST_F(ProjectStorage, SynchronizeTypesAddAliasDeclarations)
{
- Storage::Types types{createTypesWithAliases()};
+ auto package{createSynchronizationPackageWithAliases()};
- storage.synchronize(modules,
- imports,
- types,
- {sourceId1,
- sourceId2,
- sourceId3,
- sourceId4,
- qmlModuleSourceId,
- qtQuickModuleSourceId,
- pathToModuleSourceId},
- {});
+ storage.synchronize(package);
ASSERT_THAT(storage.fetchTypes(),
Contains(AllOf(
- IsStorageType(qtQuickModuleId,
+ IsStorageType(sourceId3,
"QAliasItem",
- Storage::NativeType{"QQuickItem"},
- TypeAccessSemantics::Reference,
- sourceId3),
+ fetchTypeId(sourceId1, "QQuickItem"),
+ TypeAccessSemantics::Reference),
Field(&Storage::Type::propertyDeclarations,
UnorderedElementsAre(
IsPropertyDeclaration("items",
- Storage::NativeType{"QQuickItem"},
+ fetchTypeId(sourceId1, "QQuickItem"),
Storage::PropertyDeclarationTraits::IsList
| Storage::PropertyDeclarationTraits::IsReadOnly),
IsPropertyDeclaration("objects",
- Storage::NativeType{"QObject"},
+ fetchTypeId(sourceId2, "QObject"),
Storage::PropertyDeclarationTraits::IsList),
IsPropertyDeclaration("data",
- Storage::NativeType{"QObject"},
+ fetchTypeId(sourceId2, "QObject"),
Storage::PropertyDeclarationTraits::IsList))))));
}
TEST_F(ProjectStorage, SynchronizeTypesAddAliasDeclarationsAgain)
{
- Storage::Types types{createTypesWithAliases()};
- storage.synchronize(modules,
- imports,
- types,
- {sourceId1,
- sourceId2,
- sourceId3,
- sourceId4,
- qmlModuleSourceId,
- qtQuickModuleSourceId,
- pathToModuleSourceId},
- {});
-
- storage.synchronize(modules,
- imports,
- types,
- {sourceId1,
- sourceId2,
- sourceId3,
- sourceId4,
- qmlModuleSourceId,
- qtQuickModuleSourceId,
- pathToModuleSourceId},
- {});
+ auto package{createSynchronizationPackageWithAliases()};
+ storage.synchronize(package);
+
+ storage.synchronize(package);
ASSERT_THAT(storage.fetchTypes(),
Contains(AllOf(
- IsStorageType(qtQuickModuleId,
+ IsStorageType(sourceId3,
"QAliasItem",
- Storage::NativeType{"QQuickItem"},
- TypeAccessSemantics::Reference,
- sourceId3),
+ fetchTypeId(sourceId1, "QQuickItem"),
+ TypeAccessSemantics::Reference),
Field(&Storage::Type::propertyDeclarations,
UnorderedElementsAre(
IsPropertyDeclaration("items",
- Storage::NativeType{"QQuickItem"},
+ fetchTypeId(sourceId1, "QQuickItem"),
Storage::PropertyDeclarationTraits::IsList
| Storage::PropertyDeclarationTraits::IsReadOnly),
IsPropertyDeclaration("objects",
- Storage::NativeType{"QObject"},
+ fetchTypeId(sourceId2, "QObject"),
Storage::PropertyDeclarationTraits::IsList),
IsPropertyDeclaration("data",
- Storage::NativeType{"QObject"},
+ fetchTypeId(sourceId2, "QObject"),
Storage::PropertyDeclarationTraits::IsList))))));
}
TEST_F(ProjectStorage, SynchronizeTypesRemoveAliasDeclarations)
{
- Storage::Types types{createTypesWithAliases()};
- storage.synchronize(modules,
- imports,
- types,
- {sourceId1,
- sourceId2,
- sourceId3,
- sourceId4,
- qmlModuleSourceId,
- qtQuickModuleSourceId,
- pathToModuleSourceId},
- {});
- types[2].propertyDeclarations.pop_back();
-
- storage.synchronize({}, importsSourceId3, {types[2]}, {sourceId3}, {});
+ auto package{createSynchronizationPackageWithAliases()};
+ storage.synchronize(package);
+ package.types[2].propertyDeclarations.pop_back();
+
+ storage.synchronize(SynchronizationPackage{importsSourceId3, {package.types[2]}, {sourceId3}});
ASSERT_THAT(storage.fetchTypes(),
Contains(AllOf(
- IsStorageType(qtQuickModuleId,
+ IsStorageType(sourceId3,
"QAliasItem",
- Storage::NativeType{"QQuickItem"},
- TypeAccessSemantics::Reference,
- sourceId3),
+ fetchTypeId(sourceId1, "QQuickItem"),
+ TypeAccessSemantics::Reference),
Field(&Storage::Type::propertyDeclarations,
UnorderedElementsAre(
IsPropertyDeclaration("items",
- Storage::NativeType{"QQuickItem"},
+ fetchTypeId(sourceId1, "QQuickItem"),
Storage::PropertyDeclarationTraits::IsList
| Storage::PropertyDeclarationTraits::IsReadOnly),
IsPropertyDeclaration("data",
- Storage::NativeType{"QObject"},
+ fetchTypeId(sourceId2, "QObject"),
Storage::PropertyDeclarationTraits::IsList))))));
}
TEST_F(ProjectStorage, SynchronizeTypesAddAliasDeclarationsThrowsForWrongTypeName)
{
- Storage::Types types{createTypesWithAliases()};
- types[2].propertyDeclarations[1].typeName = Storage::NativeType{"QQuickItemWrong"};
+ auto package{createSynchronizationPackageWithAliases()};
+ package.types[2].propertyDeclarations[1].typeName = Storage::ImportedType{"QQuickItemWrong"};
- ASSERT_THROW(storage.synchronize(modules, importsSourceId4, {types[2]}, {sourceId4}, {}),
+ ASSERT_THROW(storage.synchronize(
+ SynchronizationPackage{importsSourceId4, {package.types[2]}, {sourceId4}}),
QmlDesigner::TypeNameDoesNotExists);
}
TEST_F(ProjectStorage, SynchronizeTypesAddAliasDeclarationsThrowsForWrongPropertyName)
{
- Storage::Types types{createTypesWithAliases()};
- types[2].propertyDeclarations[1].aliasPropertyName = "childrenWrong";
+ auto package{createSynchronizationPackageWithAliases()};
+ package.types[2].propertyDeclarations[1].aliasPropertyName = "childrenWrong";
- ASSERT_THROW(storage.synchronize(modules, imports, types, {sourceId4}, {}),
+ ASSERT_THROW(storage.synchronize(
+ SynchronizationPackage{package.imports, package.types, {sourceId4}}),
QmlDesigner::PropertyNameDoesNotExists);
}
TEST_F(ProjectStorage, SynchronizeTypesChangeAliasDeclarationsTypeName)
{
- Storage::Types types{createTypesWithAliases()};
- storage.synchronize(modules,
- imports,
- types,
- {sourceId1,
- sourceId2,
- sourceId3,
- sourceId4,
- qmlModuleSourceId,
- qtQuickModuleSourceId,
- pathToModuleSourceId},
- {});
- types[2].propertyDeclarations[2].typeName = Storage::ImportedType{"Obj2"};
- importsSourceId3.emplace_back("/path/to", Storage::Version{}, sourceId3);
-
- storage.synchronize({}, importsSourceId3, {types[2]}, {sourceId3}, {});
+ auto package{createSynchronizationPackageWithAliases()};
+ storage.synchronize(package);
+ package.types[2].propertyDeclarations[2].typeName = Storage::ImportedType{"Obj2"};
+ importsSourceId3.emplace_back(pathToModuleId, Storage::Version{}, sourceId3);
+
+ storage.synchronize(SynchronizationPackage{importsSourceId3, {package.types[2]}, {sourceId3}});
ASSERT_THAT(storage.fetchTypes(),
Contains(AllOf(
- IsStorageType(qtQuickModuleId,
+ IsStorageType(sourceId3,
"QAliasItem",
- Storage::NativeType{"QQuickItem"},
- TypeAccessSemantics::Reference,
- sourceId3),
+ fetchTypeId(sourceId1, "QQuickItem"),
+ TypeAccessSemantics::Reference),
Field(&Storage::Type::propertyDeclarations,
UnorderedElementsAre(
IsPropertyDeclaration("items",
- Storage::NativeType{"QQuickItem"},
+ fetchTypeId(sourceId1, "QQuickItem"),
Storage::PropertyDeclarationTraits::IsList
| Storage::PropertyDeclarationTraits::IsReadOnly),
IsPropertyDeclaration("objects",
- Storage::NativeType{"QObject"},
+ fetchTypeId(sourceId2, "QObject"),
Storage::PropertyDeclarationTraits::IsList),
IsPropertyDeclaration("data",
- Storage::NativeType{"QObject"},
+ fetchTypeId(sourceId2, "QObject"),
Storage::PropertyDeclarationTraits::IsList))))));
}
TEST_F(ProjectStorage, SynchronizeTypesChangeAliasDeclarationsPropertyName)
{
- Storage::Types types{createTypesWithAliases()};
- storage.synchronize(modules,
- imports,
- types,
- {sourceId1,
- sourceId2,
- sourceId3,
- sourceId4,
- qmlModuleSourceId,
- qtQuickModuleSourceId,
- pathToModuleSourceId},
- {});
- types[2].propertyDeclarations[2].aliasPropertyName = "children";
-
- storage.synchronize({}, importsSourceId3, {types[2]}, {sourceId3}, {});
+ auto package{createSynchronizationPackageWithAliases()};
+ storage.synchronize(package);
+ package.types[2].propertyDeclarations[2].aliasPropertyName = "children";
+
+ storage.synchronize(SynchronizationPackage{importsSourceId3, {package.types[2]}, {sourceId3}});
ASSERT_THAT(
storage.fetchTypes(),
Contains(
- AllOf(IsStorageType(qtQuickModuleId,
+ AllOf(IsStorageType(sourceId3,
"QAliasItem",
- Storage::NativeType{"QQuickItem"},
- TypeAccessSemantics::Reference,
- sourceId3),
+ fetchTypeId(sourceId1, "QQuickItem"),
+ TypeAccessSemantics::Reference),
Field(&Storage::Type::propertyDeclarations,
UnorderedElementsAre(
IsPropertyDeclaration("items",
- Storage::NativeType{"QQuickItem"},
+ fetchTypeId(sourceId1, "QQuickItem"),
Storage::PropertyDeclarationTraits::IsList
| Storage::PropertyDeclarationTraits::IsReadOnly),
IsPropertyDeclaration("objects",
- Storage::NativeType{"QQuickItem"},
+ fetchTypeId(sourceId1, "QQuickItem"),
Storage::PropertyDeclarationTraits::IsList
| Storage::PropertyDeclarationTraits::IsReadOnly),
IsPropertyDeclaration("data",
- Storage::NativeType{"QObject"},
+ fetchTypeId(sourceId2, "QObject"),
Storage::PropertyDeclarationTraits::IsList))))));
}
TEST_F(ProjectStorage, SynchronizeTypesChangeAliasDeclarationsToPropertyDeclaration)
{
- Storage::Types types{createTypesWithAliases()};
- storage.synchronize(modules,
- imports,
- types,
- {sourceId1,
- sourceId2,
- sourceId3,
- sourceId4,
- qmlModuleSourceId,
- qtQuickModuleSourceId,
- pathToModuleSourceId},
- {});
- types[2].propertyDeclarations.pop_back();
- types[2].propertyDeclarations.push_back(
+ auto package{createSynchronizationPackageWithAliases()};
+ storage.synchronize(package);
+ package.types[2].propertyDeclarations.pop_back();
+ package.types[2].propertyDeclarations.push_back(
Storage::PropertyDeclaration{"objects",
- Storage::NativeType{"QQuickItem"},
+ Storage::ImportedType{"QQuickItem"},
Storage::PropertyDeclarationTraits::IsList
| Storage::PropertyDeclarationTraits::IsReadOnly});
- storage.synchronize({}, importsSourceId3, {types[2]}, {sourceId3}, {});
+ storage.synchronize(SynchronizationPackage{importsSourceId3, {package.types[2]}, {sourceId3}});
ASSERT_THAT(
storage.fetchTypes(),
Contains(
- AllOf(IsStorageType(qtQuickModuleId,
+ AllOf(IsStorageType(sourceId3,
"QAliasItem",
- Storage::NativeType{"QQuickItem"},
- TypeAccessSemantics::Reference,
- sourceId3),
+ fetchTypeId(sourceId1, "QQuickItem"),
+ TypeAccessSemantics::Reference),
Field(&Storage::Type::propertyDeclarations,
UnorderedElementsAre(
IsPropertyDeclaration("items",
- Storage::NativeType{"QQuickItem"},
+ fetchTypeId(sourceId1, "QQuickItem"),
Storage::PropertyDeclarationTraits::IsList
| Storage::PropertyDeclarationTraits::IsReadOnly),
IsPropertyDeclaration("objects",
- Storage::NativeType{"QQuickItem"},
+ fetchTypeId(sourceId1, "QQuickItem"),
Storage::PropertyDeclarationTraits::IsList
| Storage::PropertyDeclarationTraits::IsReadOnly),
IsPropertyDeclaration("data",
- Storage::NativeType{"QObject"},
+ fetchTypeId(sourceId2, "QObject"),
Storage::PropertyDeclarationTraits::IsList))))));
}
TEST_F(ProjectStorage, SynchronizeTypesChangePropertyDeclarationsToAliasDeclaration)
{
- Storage::Types types{createTypesWithAliases()};
- auto typesChanged = types;
- typesChanged[2].propertyDeclarations.pop_back();
- typesChanged[2].propertyDeclarations.push_back(
+ auto package{createSynchronizationPackageWithAliases()};
+ auto packageChanged = package;
+ packageChanged.types[2].propertyDeclarations.pop_back();
+ packageChanged.types[2].propertyDeclarations.push_back(
Storage::PropertyDeclaration{"objects",
- Storage::NativeType{"QQuickItem"},
+ Storage::ImportedType{"QQuickItem"},
Storage::PropertyDeclarationTraits::IsList
| Storage::PropertyDeclarationTraits::IsReadOnly});
- storage.synchronize(modules,
- imports,
- typesChanged,
- {sourceId1,
- sourceId2,
- sourceId3,
- sourceId4,
- qmlModuleSourceId,
- qtQuickModuleSourceId,
- pathToModuleSourceId},
- {});
-
- storage.synchronize({}, imports, types, {sourceId1, sourceId2, sourceId3, sourceId4}, {});
+ storage.synchronize(packageChanged);
+
+ storage.synchronize(package);
ASSERT_THAT(storage.fetchTypes(),
Contains(AllOf(
- IsStorageType(qtQuickModuleId,
+ IsStorageType(sourceId3,
"QAliasItem",
- Storage::NativeType{"QQuickItem"},
- TypeAccessSemantics::Reference,
- sourceId3),
+ fetchTypeId(sourceId1, "QQuickItem"),
+ TypeAccessSemantics::Reference),
Field(&Storage::Type::propertyDeclarations,
UnorderedElementsAre(
IsPropertyDeclaration("items",
- Storage::NativeType{"QQuickItem"},
+ fetchTypeId(sourceId1, "QQuickItem"),
Storage::PropertyDeclarationTraits::IsList
| Storage::PropertyDeclarationTraits::IsReadOnly),
IsPropertyDeclaration("objects",
- Storage::NativeType{"QObject"},
+ fetchTypeId(sourceId2, "QObject"),
Storage::PropertyDeclarationTraits::IsList),
IsPropertyDeclaration("data",
- Storage::NativeType{"QObject"},
+ fetchTypeId(sourceId2, "QObject"),
Storage::PropertyDeclarationTraits::IsList))))));
}
TEST_F(ProjectStorage, SynchronizeTypesChangeAliasTargetPropertyDeclarationTraits)
{
- Storage::Types types{createTypesWithAliases()};
- storage.synchronize(modules,
- imports,
- types,
- {sourceId1,
- sourceId2,
- sourceId3,
- sourceId4,
- qmlModuleSourceId,
- qtQuickModuleSourceId,
- pathToModuleSourceId},
- {});
- types[1].propertyDeclarations[0].traits = Storage::PropertyDeclarationTraits::IsList
- | Storage::PropertyDeclarationTraits::IsReadOnly;
-
- storage.synchronize({}, importsSourceId2, {types[1]}, {sourceId2}, {});
+ auto package{createSynchronizationPackageWithAliases()};
+ storage.synchronize(package);
+ package.types[1].propertyDeclarations[0].traits = Storage::PropertyDeclarationTraits::IsList
+ | Storage::PropertyDeclarationTraits::IsReadOnly;
+
+ storage.synchronize(SynchronizationPackage{importsSourceId2, {package.types[1]}, {sourceId2}});
ASSERT_THAT(
storage.fetchTypes(),
Contains(
- AllOf(IsStorageType(qtQuickModuleId,
+ AllOf(IsStorageType(sourceId3,
"QAliasItem",
- Storage::NativeType{"QQuickItem"},
- TypeAccessSemantics::Reference,
- sourceId3),
+ fetchTypeId(sourceId1, "QQuickItem"),
+ TypeAccessSemantics::Reference),
Field(&Storage::Type::propertyDeclarations,
UnorderedElementsAre(
IsPropertyDeclaration("items",
- Storage::NativeType{"QQuickItem"},
+ fetchTypeId(sourceId1, "QQuickItem"),
Storage::PropertyDeclarationTraits::IsList
| Storage::PropertyDeclarationTraits::IsReadOnly),
IsPropertyDeclaration("objects",
- Storage::NativeType{"QObject"},
+ fetchTypeId(sourceId2, "QObject"),
Storage::PropertyDeclarationTraits::IsList
| Storage::PropertyDeclarationTraits::IsReadOnly),
IsPropertyDeclaration("data",
- Storage::NativeType{"QObject"},
+ fetchTypeId(sourceId2, "QObject"),
Storage::PropertyDeclarationTraits::IsList))))));
}
TEST_F(ProjectStorage, SynchronizeTypesChangeAliasTargetPropertyDeclarationTypeName)
{
- Storage::Types types{createTypesWithAliases()};
- storage.synchronize(modules,
- imports,
- types,
- {sourceId1,
- sourceId2,
- sourceId3,
- sourceId4,
- qmlModuleSourceId,
- qtQuickModuleSourceId,
- pathToModuleSourceId},
- {});
- types[1].propertyDeclarations[0].typeName = Storage::ImportedType{"Item"};
- importsSourceId2.emplace_back("QtQuick", Storage::Version{}, sourceId2);
-
- storage.synchronize({}, importsSourceId2, {types[1]}, {sourceId2}, {});
+ auto package{createSynchronizationPackageWithAliases()};
+ storage.synchronize(package);
+ package.types[1].propertyDeclarations[0].typeName = Storage::ImportedType{"Item"};
+ importsSourceId2.emplace_back(qtQuickModuleId, Storage::Version{}, sourceId2);
+
+ storage.synchronize(SynchronizationPackage{importsSourceId2, {package.types[1]}, {sourceId2}});
ASSERT_THAT(storage.fetchTypes(),
Contains(AllOf(
- IsStorageType(qtQuickModuleId,
+ IsStorageType(sourceId3,
"QAliasItem",
- Storage::NativeType{"QQuickItem"},
- TypeAccessSemantics::Reference,
- sourceId3),
+ fetchTypeId(sourceId1, "QQuickItem"),
+ TypeAccessSemantics::Reference),
Field(&Storage::Type::propertyDeclarations,
UnorderedElementsAre(
IsPropertyDeclaration("items",
- Storage::NativeType{"QQuickItem"},
+ fetchTypeId(sourceId1, "QQuickItem"),
Storage::PropertyDeclarationTraits::IsList
| Storage::PropertyDeclarationTraits::IsReadOnly),
IsPropertyDeclaration("objects",
- Storage::NativeType{"QQuickItem"},
+ fetchTypeId(sourceId1, "QQuickItem"),
Storage::PropertyDeclarationTraits::IsList),
IsPropertyDeclaration("data",
- Storage::NativeType{"QObject"},
+ fetchTypeId(sourceId2, "QObject"),
Storage::PropertyDeclarationTraits::IsList))))));
}
TEST_F(ProjectStorage, SynchronizeTypesRemovePropertyDeclarationWithAnAliasThrows)
{
- Storage::Types types{createTypesWithAliases()};
- storage.synchronize(modules,
- imports,
- types,
- {sourceId1,
- sourceId2,
- sourceId3,
- sourceId4,
- qmlModuleSourceId,
- qtQuickModuleSourceId,
- pathToModuleSourceId},
- {});
- types[1].propertyDeclarations.pop_back();
-
- ASSERT_THROW(storage.synchronize({}, importsSourceId2, {types[1]}, {sourceId2}, {}),
+ auto package{createSynchronizationPackageWithAliases()};
+ storage.synchronize(package);
+ package.types[1].propertyDeclarations.pop_back();
+
+ ASSERT_THROW(storage.synchronize(
+ SynchronizationPackage{importsSourceId2, {package.types[1]}, {sourceId2}}),
Sqlite::ConstraintPreventsModification);
}
TEST_F(ProjectStorage, SynchronizeTypesRemovePropertyDeclarationAndAlias)
{
- Storage::Types types{createTypesWithAliases()};
- storage.synchronize(modules,
- imports,
- types,
- {sourceId1,
- sourceId2,
- sourceId3,
- sourceId4,
- qmlModuleSourceId,
- qtQuickModuleSourceId,
- pathToModuleSourceId},
- {});
- types[1].propertyDeclarations.pop_back();
- types[2].propertyDeclarations.pop_back();
-
- storage.synchronize({},
- importsSourceId2 + importsSourceId3,
- {types[1], types[2]},
- {sourceId2, sourceId3},
- {});
+ auto package{createSynchronizationPackageWithAliases()};
+ storage.synchronize(package);
+ package.types[1].propertyDeclarations.pop_back();
+ package.types[2].propertyDeclarations.pop_back();
+
+ storage.synchronize(SynchronizationPackage{importsSourceId2 + importsSourceId3,
+ {package.types[1], package.types[2]},
+ {sourceId2, sourceId3}});
ASSERT_THAT(storage.fetchTypes(),
Contains(AllOf(
- IsStorageType(qtQuickModuleId,
+ IsStorageType(sourceId3,
"QAliasItem",
- Storage::NativeType{"QQuickItem"},
- TypeAccessSemantics::Reference,
- sourceId3),
+ fetchTypeId(sourceId1, "QQuickItem"),
+ TypeAccessSemantics::Reference),
Field(&Storage::Type::propertyDeclarations,
UnorderedElementsAre(
IsPropertyDeclaration("items",
- Storage::NativeType{"QQuickItem"},
+ fetchTypeId(sourceId1, "QQuickItem"),
Storage::PropertyDeclarationTraits::IsList
| Storage::PropertyDeclarationTraits::IsReadOnly),
IsPropertyDeclaration("data",
- Storage::NativeType{"QObject"},
+ fetchTypeId(sourceId2, "QObject"),
Storage::PropertyDeclarationTraits::IsList))))));
}
TEST_F(ProjectStorage, SynchronizeTypesRemoveTypeWithAliasTargetPropertyDeclarationThrows)
{
- Storage::Types types{createTypesWithAliases()};
- types[2].propertyDeclarations[2].typeName = Storage::ImportedType{"Object2"};
- imports.emplace_back("/path/to", Storage::Version{}, sourceId3);
- storage.synchronize(modules,
- imports,
- types,
- {sourceId1,
- sourceId2,
- sourceId3,
- sourceId4,
- qmlModuleSourceId,
- qtQuickModuleSourceId,
- pathToModuleSourceId},
- {});
+ auto package{createSynchronizationPackageWithAliases()};
+ package.types[2].propertyDeclarations[2].typeName = Storage::ImportedType{"Object2"};
+ package.imports.emplace_back(pathToModuleId, Storage::Version{}, sourceId3);
+ storage.synchronize(package);
- ASSERT_THROW(storage.synchronize({}, {}, {}, {sourceId4}, {}), QmlDesigner::TypeNameDoesNotExists);
+ ASSERT_THROW(storage.synchronize(SynchronizationPackage{{sourceId4}}),
+ QmlDesigner::TypeNameDoesNotExists);
}
TEST_F(ProjectStorage, SynchronizeTypesRemoveTypeAndAliasPropertyDeclaration)
{
- Storage::Types types{createTypesWithAliases()};
- types[2].propertyDeclarations[2].typeName = Storage::ImportedType{"Object2"};
- imports.emplace_back("/path/to", Storage::Version{}, sourceId3);
- storage.synchronize(modules,
- imports,
- types,
- {sourceId1,
- sourceId2,
- sourceId3,
- sourceId4,
- qmlModuleSourceId,
- qtQuickModuleSourceId,
- pathToModuleSourceId},
- {});
- types[2].propertyDeclarations.pop_back();
-
- storage.synchronize({},
- importsSourceId1 + importsSourceId3,
- {types[0], types[2]},
- {sourceId1, sourceId3},
- {});
+ auto package{createSynchronizationPackageWithAliases()};
+ package.types[2].propertyDeclarations[2].typeName = Storage::ImportedType{"Object2"};
+ package.imports.emplace_back(pathToModuleId, Storage::Version{}, sourceId3);
+ storage.synchronize(package);
+ package.types[2].propertyDeclarations.pop_back();
+
+ storage.synchronize(SynchronizationPackage{importsSourceId1 + importsSourceId3,
+ {package.types[0], package.types[2]},
+ {sourceId1, sourceId3}});
ASSERT_THAT(storage.fetchTypes(),
Contains(AllOf(
- IsStorageType(qtQuickModuleId,
+ IsStorageType(sourceId3,
"QAliasItem",
- Storage::NativeType{"QQuickItem"},
- TypeAccessSemantics::Reference,
- sourceId3),
+ fetchTypeId(sourceId1, "QQuickItem"),
+ TypeAccessSemantics::Reference),
Field(&Storage::Type::propertyDeclarations,
UnorderedElementsAre(
IsPropertyDeclaration("items",
- Storage::NativeType{"QQuickItem"},
+ fetchTypeId(sourceId1, "QQuickItem"),
Storage::PropertyDeclarationTraits::IsList
| Storage::PropertyDeclarationTraits::IsReadOnly),
IsPropertyDeclaration("data",
- Storage::NativeType{"QObject"},
+ fetchTypeId(sourceId2, "QObject"),
Storage::PropertyDeclarationTraits::IsList))))));
}
TEST_F(ProjectStorage, UpdateAliasPropertyIfPropertyIsOverloaded)
{
- Storage::Types types{createTypesWithAliases()};
- storage.synchronize(modules,
- imports,
- types,
- {sourceId1,
- sourceId2,
- sourceId3,
- sourceId4,
- qmlModuleSourceId,
- qtQuickModuleSourceId,
- pathToModuleSourceId},
- {});
- types[0].propertyDeclarations.push_back(
+ auto package{createSynchronizationPackageWithAliases()};
+ storage.synchronize(package);
+ package.types[0].propertyDeclarations.push_back(
Storage::PropertyDeclaration{"objects",
- Storage::NativeType{"QQuickItem"},
+ Storage::ImportedType{"QQuickItem"},
Storage::PropertyDeclarationTraits::IsList
| Storage::PropertyDeclarationTraits::IsReadOnly});
- storage.synchronize({}, importsSourceId1, {types[0]}, {sourceId1}, {});
+ storage.synchronize(SynchronizationPackage{importsSourceId1, {package.types[0]}, {sourceId1}});
ASSERT_THAT(
storage.fetchTypes(),
Contains(
- AllOf(IsStorageType(qtQuickModuleId,
+ AllOf(IsStorageType(sourceId3,
"QAliasItem",
- Storage::NativeType{"QQuickItem"},
- TypeAccessSemantics::Reference,
- sourceId3),
+ fetchTypeId(sourceId1, "QQuickItem"),
+ TypeAccessSemantics::Reference),
Field(&Storage::Type::propertyDeclarations,
UnorderedElementsAre(
IsPropertyDeclaration("items",
- Storage::NativeType{"QQuickItem"},
+ fetchTypeId(sourceId1, "QQuickItem"),
Storage::PropertyDeclarationTraits::IsList
| Storage::PropertyDeclarationTraits::IsReadOnly),
IsPropertyDeclaration("objects",
- Storage::NativeType{"QQuickItem"},
+ fetchTypeId(sourceId1, "QQuickItem"),
Storage::PropertyDeclarationTraits::IsList
| Storage::PropertyDeclarationTraits::IsReadOnly),
IsPropertyDeclaration("data",
- Storage::NativeType{"QObject"},
+ fetchTypeId(sourceId2, "QObject"),
Storage::PropertyDeclarationTraits::IsList))))));
}
TEST_F(ProjectStorage, AliasPropertyIsOverloaded)
{
- Storage::Types types{createTypesWithAliases()};
- types[0].propertyDeclarations.push_back(
+ auto package{createSynchronizationPackageWithAliases()};
+ package.types[0].propertyDeclarations.push_back(
Storage::PropertyDeclaration{"objects",
- Storage::NativeType{"QQuickItem"},
+ Storage::ImportedType{"QQuickItem"},
Storage::PropertyDeclarationTraits::IsList
| Storage::PropertyDeclarationTraits::IsReadOnly});
- storage.synchronize(modules,
- imports,
- types,
- {sourceId1,
- sourceId2,
- sourceId3,
- sourceId4,
- qmlModuleSourceId,
- qtQuickModuleSourceId,
- pathToModuleSourceId},
- {});
+ storage.synchronize(package);
ASSERT_THAT(
storage.fetchTypes(),
Contains(
- AllOf(IsStorageType(qtQuickModuleId,
+ AllOf(IsStorageType(sourceId3,
"QAliasItem",
- Storage::NativeType{"QQuickItem"},
- TypeAccessSemantics::Reference,
- sourceId3),
+ fetchTypeId(sourceId1, "QQuickItem"),
+ TypeAccessSemantics::Reference),
Field(&Storage::Type::propertyDeclarations,
UnorderedElementsAre(
IsPropertyDeclaration("items",
- Storage::NativeType{"QQuickItem"},
+ fetchTypeId(sourceId1, "QQuickItem"),
Storage::PropertyDeclarationTraits::IsList
| Storage::PropertyDeclarationTraits::IsReadOnly),
IsPropertyDeclaration("objects",
- Storage::NativeType{"QQuickItem"},
+ fetchTypeId(sourceId1, "QQuickItem"),
Storage::PropertyDeclarationTraits::IsList
| Storage::PropertyDeclarationTraits::IsReadOnly),
IsPropertyDeclaration("data",
- Storage::NativeType{"QObject"},
+ fetchTypeId(sourceId2, "QObject"),
Storage::PropertyDeclarationTraits::IsList))))));
}
TEST_F(ProjectStorage, UpdateAliasPropertyIfOverloadedPropertyIsRemoved)
{
- Storage::Types types{createTypesWithAliases()};
- types[0].propertyDeclarations.push_back(
+ auto package{createSynchronizationPackageWithAliases()};
+ package.types[0].propertyDeclarations.push_back(
Storage::PropertyDeclaration{"objects",
- Storage::NativeType{"QQuickItem"},
+ Storage::ImportedType{"QQuickItem"},
Storage::PropertyDeclarationTraits::IsList
| Storage::PropertyDeclarationTraits::IsReadOnly});
- storage.synchronize(modules,
- imports,
- types,
- {sourceId1,
- sourceId2,
- sourceId3,
- sourceId4,
- qmlModuleSourceId,
- qtQuickModuleSourceId,
- pathToModuleSourceId},
- {});
- types[0].propertyDeclarations.pop_back();
-
- storage.synchronize({}, importsSourceId1, {types[0]}, {sourceId1}, {});
+ storage.synchronize(package);
+ package.types[0].propertyDeclarations.pop_back();
+
+ storage.synchronize(SynchronizationPackage{importsSourceId1, {package.types[0]}, {sourceId1}});
ASSERT_THAT(storage.fetchTypes(),
Contains(AllOf(
- IsStorageType(qtQuickModuleId,
+ IsStorageType(sourceId3,
"QAliasItem",
- Storage::NativeType{"QQuickItem"},
- TypeAccessSemantics::Reference,
- sourceId3),
+ fetchTypeId(sourceId1, "QQuickItem"),
+ TypeAccessSemantics::Reference),
Field(&Storage::Type::propertyDeclarations,
UnorderedElementsAre(
IsPropertyDeclaration("items",
- Storage::NativeType{"QQuickItem"},
+ fetchTypeId(sourceId1, "QQuickItem"),
Storage::PropertyDeclarationTraits::IsList
| Storage::PropertyDeclarationTraits::IsReadOnly),
IsPropertyDeclaration("objects",
- Storage::NativeType{"QObject"},
+ fetchTypeId(sourceId2, "QObject"),
Storage::PropertyDeclarationTraits::IsList),
IsPropertyDeclaration("data",
- Storage::NativeType{"QObject"},
+ fetchTypeId(sourceId2, "QObject"),
Storage::PropertyDeclarationTraits::IsList))))));
}
TEST_F(ProjectStorage, RelinkAliasProperty)
{
- Storage::Types types{createTypesWithAliases()};
- types[1].propertyDeclarations[0].typeName = Storage::NativeType{"QObject2"};
- imports.emplace_back("/path/to", Storage::Version{}, sourceId2);
- imports.emplace_back("QtQuick", Storage::Version{}, sourceId2);
- storage.synchronize(modules,
- imports,
- types,
- {sourceId1,
- sourceId2,
- sourceId3,
- sourceId4,
- qmlModuleSourceId,
- qtQuickModuleSourceId,
- pathToModuleSourceId},
- {});
- types[3].moduleId = qtQuickModuleId;
-
- storage.synchronize({}, importsSourceId4, {types[3]}, {sourceId4}, {});
+ auto package{createSynchronizationPackageWithAliases()};
+ package.types[1].propertyDeclarations[0].typeName = Storage::ImportedType{"Object2"};
+ package.imports.emplace_back(pathToModuleId, Storage::Version{}, sourceId2);
+ package.imports.emplace_back(qtQuickModuleId, Storage::Version{}, sourceId2);
+ storage.synchronize(package);
+ package.types[3].exportedTypes[0].moduleId = qtQuickModuleId;
+
+ storage.synchronize(SynchronizationPackage{importsSourceId4, {package.types[3]}, {sourceId4}});
ASSERT_THAT(storage.fetchTypes(),
Contains(AllOf(
- IsStorageType(qtQuickModuleId,
+ IsStorageType(sourceId3,
"QAliasItem",
- Storage::NativeType{"QQuickItem"},
- TypeAccessSemantics::Reference,
- sourceId3),
+ fetchTypeId(sourceId1, "QQuickItem"),
+ TypeAccessSemantics::Reference),
Field(&Storage::Type::propertyDeclarations,
UnorderedElementsAre(
IsPropertyDeclaration("items",
- Storage::NativeType{"QQuickItem"},
+ fetchTypeId(sourceId1, "QQuickItem"),
Storage::PropertyDeclarationTraits::IsList
| Storage::PropertyDeclarationTraits::IsReadOnly),
IsPropertyDeclaration("objects",
- Storage::NativeType{"QObject2"},
+ fetchTypeId(sourceId4, "QObject2"),
Storage::PropertyDeclarationTraits::IsList),
IsPropertyDeclaration("data",
- Storage::NativeType{"QObject"},
+ fetchTypeId(sourceId2, "QObject"),
Storage::PropertyDeclarationTraits::IsList))))));
}
TEST_F(ProjectStorage, DoNotRelinkAliasPropertyForQualifiedImportedTypeName)
{
- Storage::Types types{createTypesWithAliases()};
- types[1].propertyDeclarations[0].typeName = Storage::QualifiedImportedType{
- "Object2", Storage::Import{"/path/to", Storage::Version{}, sourceId2}};
- imports.emplace_back("/path/to", Storage::Version{}, sourceId2);
- storage.synchronize(modules,
- imports,
- types,
- {sourceId1,
- sourceId2,
- sourceId3,
- sourceId4,
- qmlModuleSourceId,
- qtQuickModuleSourceId,
- pathToModuleSourceId},
- {});
- types[3].moduleId = qtQuickModuleId;
- importsSourceId4.emplace_back("QtQuick", Storage::Version{}, sourceId4);
-
- ASSERT_THROW(storage.synchronize({}, importsSourceId4, {types[3]}, {sourceId4}, {}),
+ auto package{createSynchronizationPackageWithAliases()};
+ package.types[1].propertyDeclarations[0].typeName = Storage::QualifiedImportedType{
+ "Object2", Storage::Import{pathToModuleId, Storage::Version{}, sourceId2}};
+ package.imports.emplace_back(pathToModuleId, Storage::Version{}, sourceId2);
+ storage.synchronize(package);
+ package.types[3].exportedTypes[0].moduleId = qtQuickModuleId;
+ importsSourceId4.emplace_back(qtQuickModuleId, Storage::Version{}, sourceId4);
+
+ ASSERT_THROW(storage.synchronize(
+ SynchronizationPackage{importsSourceId4, {package.types[3]}, {sourceId4}}),
QmlDesigner::TypeNameDoesNotExists);
}
TEST_F(ProjectStorage,
DoRelinkAliasPropertyForQualifiedImportedTypeNameEvenIfAnOtherSimilarTimeNameExists)
{
- Storage::Types types{createTypesWithAliases()};
- types[1].propertyDeclarations[0].typeName = Storage::QualifiedImportedType{
- "Object2", Storage::Import{"/path/to", Storage::Version{}, sourceId2}};
- imports.emplace_back("/path/to", Storage::Version{}, sourceId2);
- types.push_back(Storage::Type{qtQuickModuleId,
- "QObject2",
- Storage::NativeType{},
- TypeAccessSemantics::Reference,
- sourceId5,
- {Storage::ExportedType{"Object2"}, Storage::ExportedType{"Obj2"}}});
-
- storage.synchronize(modules,
- imports,
- types,
- {sourceId1,
- sourceId2,
- sourceId3,
- sourceId4,
- sourceId5,
- qmlModuleSourceId,
- qtQuickModuleSourceId,
- pathToModuleSourceId},
- {});
+ auto package{createSynchronizationPackageWithAliases()};
+ package.types[1].propertyDeclarations[0].typeName = Storage::QualifiedImportedType{
+ "Object2", Storage::Import{pathToModuleId, Storage::Version{}, sourceId2}};
+ package.imports.emplace_back(pathToModuleId, Storage::Version{}, sourceId2);
+ package.types.push_back(Storage::Type{"QObject2",
+ Storage::ImportedType{},
+ TypeAccessSemantics::Reference,
+ sourceId5,
+ {Storage::ExportedType{qtQuickModuleId, "Object2"},
+ Storage::ExportedType{qtQuickModuleId, "Obj2"}}});
+ package.sourceIds.push_back(sourceId5);
+
+ storage.synchronize(package);
ASSERT_THAT(storage.fetchTypes(),
Contains(AllOf(
- IsStorageType(qtQuickModuleId,
+ IsStorageType(sourceId3,
"QAliasItem",
- Storage::NativeType{"QQuickItem"},
- TypeAccessSemantics::Reference,
- sourceId3),
+ fetchTypeId(sourceId1, "QQuickItem"),
+ TypeAccessSemantics::Reference),
Field(&Storage::Type::propertyDeclarations,
UnorderedElementsAre(
IsPropertyDeclaration("items",
- Storage::NativeType{"QQuickItem"},
+ fetchTypeId(sourceId1, "QQuickItem"),
Storage::PropertyDeclarationTraits::IsList
| Storage::PropertyDeclarationTraits::IsReadOnly),
IsPropertyDeclaration("objects",
- Storage::NativeType{"QObject2"},
+ fetchTypeId(sourceId4, "QObject2"),
Storage::PropertyDeclarationTraits::IsList),
IsPropertyDeclaration("data",
- Storage::NativeType{"QObject"},
+ fetchTypeId(sourceId2, "QObject"),
Storage::PropertyDeclarationTraits::IsList))))));
}
TEST_F(ProjectStorage, RelinkAliasPropertyReactToTypeNameChange)
{
- Storage::Types types{createTypesWithAliases2()};
- types[2].propertyDeclarations.push_back(
+ auto package{createSynchronizationPackageWithAliases2()};
+ package.types[2].propertyDeclarations.push_back(
Storage::PropertyDeclaration{"items", Storage::ImportedType{"Item"}, "children"});
- storage.synchronize(modules,
- imports,
- types,
- {sourceId1,
- sourceId2,
- sourceId3,
- sourceId4,
- qmlModuleSourceId,
- qtQuickModuleSourceId,
- pathToModuleSourceId},
- {});
- types[0].typeName = "QQuickItem2";
-
- storage.synchronize({}, importsSourceId1, {types[0]}, {sourceId1}, {});
+ storage.synchronize(package);
+ package.types[0].typeName = "QQuickItem2";
+
+ storage.synchronize(SynchronizationPackage{importsSourceId1, {package.types[0]}, {sourceId1}});
ASSERT_THAT(storage.fetchTypes(),
Contains(AllOf(
- IsStorageType(qtQuickModuleId,
+ IsStorageType(sourceId3,
"QAliasItem",
- Storage::NativeType{"QObject"},
- TypeAccessSemantics::Reference,
- sourceId3),
+ fetchTypeId(sourceId2, "QObject"),
+ TypeAccessSemantics::Reference),
Field(&Storage::Type::propertyDeclarations,
UnorderedElementsAre(
IsPropertyDeclaration("items",
- Storage::NativeType{"QQuickItem2"},
+ fetchTypeId(sourceId1, "QQuickItem2"),
Storage::PropertyDeclarationTraits::IsList
| Storage::PropertyDeclarationTraits::IsReadOnly),
IsPropertyDeclaration("objects",
- Storage::NativeType{"QObject"},
+ fetchTypeId(sourceId2, "QObject"),
Storage::PropertyDeclarationTraits::IsList),
IsPropertyDeclaration("data",
- Storage::NativeType{"QObject"},
+ fetchTypeId(sourceId2, "QObject"),
Storage::PropertyDeclarationTraits::IsList))))));
}
TEST_F(ProjectStorage, DoNotRelinkAliasPropertyForDeletedType)
{
- Storage::Types types{createTypesWithAliases()};
- types[1].propertyDeclarations[0].typeName = Storage::NativeType{"QObject2"};
- imports.emplace_back("/path/to", Storage::Version{}, sourceId2);
- imports.emplace_back("QtQuick", Storage::Version{}, sourceId2);
-
- storage.synchronize(modules,
- imports,
- types,
- {sourceId1,
- sourceId2,
- sourceId3,
- sourceId4,
- qmlModuleSourceId,
- qtQuickModuleSourceId,
- pathToModuleSourceId},
- {});
- types[3].moduleId = qtQuickModuleId;
-
- storage.synchronize({}, importsSourceId4, {types[3]}, {sourceId3, sourceId4}, {});
+ auto package{createSynchronizationPackageWithAliases()};
+ package.types[1].propertyDeclarations[0].typeName = Storage::ImportedType{"Object2"};
+ package.imports.emplace_back(pathToModuleId, Storage::Version{}, sourceId2);
+ package.imports.emplace_back(qtQuickModuleId, Storage::Version{}, sourceId2);
+ storage.synchronize(package);
+ package.types[3].exportedTypes[0].moduleId = qtQuickModuleId;
+
+ storage.synchronize(
+ SynchronizationPackage{importsSourceId4, {package.types[3]}, {sourceId3, sourceId4}});
ASSERT_THAT(storage.fetchTypes(),
- Not(Contains(AllOf(IsStorageType(qtQuickModuleId,
- "QAliasItem",
- Storage::NativeType{"QQuickItem"},
- TypeAccessSemantics::Reference,
- sourceId3)))));
+ Not(Contains(IsStorageType(sourceId3,
+ "QAliasItem",
+ fetchTypeId(sourceId1, "QQuickItem"),
+ TypeAccessSemantics::Reference))));
}
TEST_F(ProjectStorage, DoNotRelinkAliasPropertyForDeletedTypeAndPropertyType)
{
- Storage::Types types{createTypesWithAliases()};
- types[1].propertyDeclarations[0].typeName = Storage::NativeType{"QObject2"};
- imports.emplace_back("/path/to", Storage::Version{}, sourceId2);
- storage.synchronize(modules,
- imports,
- types,
- {sourceId1,
- sourceId2,
- sourceId3,
- sourceId4,
- qmlModuleSourceId,
- qtQuickModuleSourceId,
- pathToModuleSourceId},
- {});
- types[0].prototype = Storage::NativeType{};
- importsSourceId1.emplace_back("/path/to", Storage::Version{}, sourceId1);
- importsSourceId4.emplace_back("QtQuick", Storage::Version{}, sourceId4);
- types[0].propertyDeclarations[0].typeName = Storage::ImportedType{"Object2"};
- types[3].propertyDeclarations[0].typeName = Storage::ImportedType{"Item"};
-
- storage.synchronize({},
- importsSourceId1 + importsSourceId4,
- {types[0], types[3]},
- {sourceId1, sourceId2, sourceId3, sourceId4},
- {});
+ auto package{createSynchronizationPackageWithAliases()};
+ package.types[1].propertyDeclarations[0].typeName = Storage::ImportedType{"Object2"};
+ package.imports.emplace_back(pathToModuleId, Storage::Version{}, sourceId2);
+ package.imports.emplace_back(qtQuickModuleId, Storage::Version{}, sourceId2);
+ storage.synchronize(package);
+ package.types[0].prototype = Storage::ImportedType{};
+ importsSourceId1.emplace_back(pathToModuleId, Storage::Version{}, sourceId1);
+ importsSourceId4.emplace_back(qtQuickModuleId, Storage::Version{}, sourceId4);
+ package.types[0].propertyDeclarations[0].typeName = Storage::ImportedType{"Object2"};
+ package.types[3].propertyDeclarations[0].typeName = Storage::ImportedType{"Item"};
+
+ storage.synchronize(SynchronizationPackage{importsSourceId1 + importsSourceId4,
+ {package.types[0], package.types[3]},
+ {sourceId1, sourceId2, sourceId3, sourceId4}});
ASSERT_THAT(storage.fetchTypes(), SizeIs(2));
}
TEST_F(ProjectStorage, DoNotRelinkAliasPropertyForDeletedTypeAndPropertyTypeNameChange)
{
- Storage::Types types{createTypesWithAliases()};
- types[1].propertyDeclarations[0].typeName = Storage::NativeType{"QObject2"};
- imports.emplace_back("/path/to", Storage::Version{}, sourceId2);
- storage.synchronize(modules,
- imports,
- types,
- {sourceId1,
- sourceId2,
- sourceId3,
- sourceId4,
- qmlModuleSourceId,
- qtQuickModuleSourceId,
- pathToModuleSourceId},
- {});
- types[3].moduleId = qtQuickModuleId;
- types[1].propertyDeclarations[0].typeName = Storage::NativeType{"QObject"};
- importsSourceId4.emplace_back("QtQuick", Storage::Version{}, sourceId4);
-
- storage.synchronize({},
- importsSourceId2 + importsSourceId4,
- {types[1], types[3]},
- {sourceId2, sourceId3, sourceId4},
- {});
+ auto package{createSynchronizationPackageWithAliases()};
+ package.types[1].propertyDeclarations[0].typeName = Storage::ImportedType{"Object2"};
+ package.imports.emplace_back(pathToModuleId, Storage::Version{}, sourceId2);
+ storage.synchronize(package);
+ package.types[3].exportedTypes[0].moduleId = qtQuickModuleId;
+ package.types[1].propertyDeclarations[0].typeName = Storage::ImportedType{"QObject"};
+ importsSourceId4.emplace_back(qtQuickModuleId, Storage::Version{}, sourceId4);
+
+ storage.synchronize(SynchronizationPackage{importsSourceId2 + importsSourceId4,
+ {package.types[1], package.types[3]},
+ {sourceId2, sourceId3, sourceId4}});
ASSERT_THAT(storage.fetchTypes(),
- Not(Contains(IsStorageType(qtQuickModuleId,
+ Not(Contains(IsStorageType(sourceId3,
"QAliasItem",
- Storage::NativeType{"QQuickItem"},
- TypeAccessSemantics::Reference,
- sourceId3))));
+ fetchTypeId(sourceId1, "QQuickItem"),
+ TypeAccessSemantics::Reference))));
}
TEST_F(ProjectStorage, DoNotRelinkPropertyTypeDoesNotExists)
{
- Storage::Types types{createTypesWithAliases()};
- types[1].propertyDeclarations[0].typeName = Storage::NativeType{"QObject2"};
- imports.emplace_back("/path/to", Storage::Version{}, sourceId2);
- imports.emplace_back("QtQuick", Storage::Version{}, sourceId2);
- storage.synchronize(modules,
- imports,
- types,
- {sourceId1,
- sourceId2,
- sourceId3,
- sourceId4,
- qmlModuleSourceId,
- qtQuickModuleSourceId,
- pathToModuleSourceId},
- {});
- types.pop_back();
-
- ASSERT_THROW(storage.synchronize({}, {}, {}, {sourceId4}, {}), QmlDesigner::TypeNameDoesNotExists);
+ auto package{createSynchronizationPackageWithAliases()};
+ package.types[1].propertyDeclarations[0].typeName = Storage::ImportedType{"Object2"};
+ package.imports.emplace_back(pathToModuleId, Storage::Version{}, sourceId2);
+ package.imports.emplace_back(qtQuickModuleId, Storage::Version{}, sourceId2);
+ storage.synchronize(package);
+
+ ASSERT_THROW(storage.synchronize(SynchronizationPackage{{sourceId4}}),
+ QmlDesigner::TypeNameDoesNotExists);
}
TEST_F(ProjectStorage, DoNotRelinkAliasPropertyTypeDoesNotExists)
{
- Storage::Types types{createTypesWithAliases2()};
- types[1].propertyDeclarations[0].typeName = Storage::NativeType{"QObject2"};
- imports.emplace_back("/path/to", Storage::Version{}, sourceId2);
- storage.synchronize(modules,
- imports,
- types,
- {sourceId1,
- sourceId2,
- sourceId3,
- sourceId4,
- qmlModuleSourceId,
- qtQuickModuleSourceId,
- pathToModuleSourceId},
- {});
+ auto package{createSynchronizationPackageWithAliases2()};
+ package.types[1].propertyDeclarations[0].typeName = Storage::ImportedType{"Object2"};
+ package.imports.emplace_back(pathToModuleId, Storage::Version{}, sourceId2);
+ storage.synchronize(package);
- ASSERT_THROW(storage.synchronize({}, {}, {}, {sourceId1}, {}), QmlDesigner::TypeNameDoesNotExists);
+ ASSERT_THROW(storage.synchronize(SynchronizationPackage{{sourceId1}}),
+ QmlDesigner::TypeNameDoesNotExists);
}
TEST_F(ProjectStorage, ChangePrototypeTypeName)
{
- Storage::Types types{createTypesWithExportedTypeNamesOnly()};
- storage.synchronize(
- modules,
- imports,
- types,
- {sourceId1, sourceId2, qmlModuleSourceId, qtQuickModuleSourceId, pathToModuleSourceId},
- {});
- types[1].typeName = "QObject3";
+ auto package{createSimpleSynchronizationPackage()};
+ storage.synchronize(package);
+ package.types[1].typeName = "QObject3";
- storage.synchronize({}, importsSourceId2, {types[1]}, {sourceId2}, {});
+ storage.synchronize(SynchronizationPackage{importsSourceId2, {package.types[1]}, {sourceId2}});
ASSERT_THAT(storage.fetchTypes(),
- Contains(IsStorageType(qtQuickModuleId,
+ Contains(IsStorageType(sourceId1,
"QQuickItem",
- Storage::NativeType{"QObject3"},
- TypeAccessSemantics::Reference,
- sourceId1)));
+ fetchTypeId(sourceId2, "QObject3"),
+ TypeAccessSemantics::Reference)));
}
TEST_F(ProjectStorage, ChangePrototypeTypeModuleId)
{
- Storage::Types types{createTypes()};
- storage.synchronize(
- modules,
- imports,
- types,
- {sourceId1, sourceId2, qmlModuleSourceId, qtQuickModuleSourceId, pathToModuleSourceId},
- {});
- types[1].moduleId = qtQuickModuleId;
+ auto package{createSimpleSynchronizationPackage()};
+ storage.synchronize(package);
+ package.types[1].exportedTypes[2].moduleId = qtQuickModuleId;
- storage.synchronize({}, importsSourceId2, {types[1]}, {sourceId2}, {});
+ storage.synchronize(SynchronizationPackage{importsSourceId2, {package.types[1]}, {sourceId2}});
ASSERT_THAT(storage.fetchTypes(),
- Contains(IsStorageType(qtQuickModuleId,
+ Contains(IsStorageType(sourceId1,
"QQuickItem",
- Storage::NativeType{"QObject"},
- TypeAccessSemantics::Reference,
- sourceId1)));
+ fetchTypeId(sourceId2, "QObject"),
+ TypeAccessSemantics::Reference)));
}
-TEST_F(ProjectStorage, ChangeQualifiedPrototypeTypeModuleIdThows)
+TEST_F(ProjectStorage, ChangeQualifiedPrototypeTypeModuleIdThrows)
{
- Storage::Types types{createTypes()};
- types[0].prototype = Storage::QualifiedImportedType{"Object",
- Storage::Import{"Qml",
- Storage::Version{},
- sourceId1}};
- storage.synchronize(
- modules,
- imports,
- types,
- {sourceId1, sourceId2, qmlModuleSourceId, qtQuickModuleSourceId, pathToModuleSourceId},
- {});
- types[1].moduleId = qtQuickModuleId;
-
- ASSERT_THROW(storage.synchronize({}, importsSourceId2, {types[1]}, {sourceId2}, {}),
+ auto package{createSimpleSynchronizationPackage()};
+ package.types[0].prototype = Storage::QualifiedImportedType{"Object",
+ Storage::Import{qmlModuleId,
+ Storage::Version{},
+ sourceId1}};
+ storage.synchronize(package);
+ package.types[1].exportedTypes[0].moduleId = qtQuickModuleId;
+
+ ASSERT_THROW(storage.synchronize(
+ SynchronizationPackage{importsSourceId2, {package.types[1]}, {sourceId2}}),
QmlDesigner::TypeNameDoesNotExists);
}
TEST_F(ProjectStorage, ChangeQualifiedPrototypeTypeModuleId)
{
- Storage::Types types{createTypes()};
- types[0].prototype = Storage::QualifiedImportedType{"Object",
- Storage::Import{"Qml",
- Storage::Version{},
- sourceId1}};
- storage.synchronize(
- modules,
- imports,
- types,
- {sourceId1, sourceId2, qmlModuleSourceId, qtQuickModuleSourceId, pathToModuleSourceId},
- {});
- types[1].moduleId = qtQuickModuleId;
- types[0].prototype = Storage::QualifiedImportedType{"Object",
- Storage::Import{"QtQuick",
- Storage::Version{},
- sourceId1}};
-
- storage.synchronize({},
- importsSourceId1 + importsSourceId2,
- {types[0], types[1]},
- {sourceId1, sourceId2},
- {});
+ auto package{createSimpleSynchronizationPackage()};
+ package.types[0].prototype = Storage::QualifiedImportedType{"Object",
+ Storage::Import{qmlModuleId,
+ Storage::Version{},
+ sourceId1}};
+ storage.synchronize(package);
+ package.types[1].exportedTypes[0].moduleId = qtQuickModuleId;
+ package.types[0].prototype = Storage::QualifiedImportedType{"Object",
+ Storage::Import{qtQuickModuleId,
+ Storage::Version{},
+ sourceId1}};
+
+ storage.synchronize(SynchronizationPackage{importsSourceId1 + importsSourceId2,
+ {package.types[0], package.types[1]},
+ {sourceId1, sourceId2}});
ASSERT_THAT(storage.fetchTypes(),
- Contains(IsStorageType(qtQuickModuleId,
+ Contains(IsStorageType(sourceId1,
"QQuickItem",
- Storage::NativeType{"QObject"},
- TypeAccessSemantics::Reference,
- sourceId1)));
+ fetchTypeId(sourceId2, "QObject"),
+ TypeAccessSemantics::Reference)));
}
TEST_F(ProjectStorage, ChangePrototypeTypeNameAndModuleId)
{
- Storage::Types types{createTypesWithExportedTypeNamesOnly()};
- storage.synchronize(
- modules,
- imports,
- types,
- {sourceId1, sourceId2, qmlModuleSourceId, qtQuickModuleSourceId, pathToModuleSourceId},
- {});
- types[1].moduleId = qtQuickModuleId;
- types[1].typeName = "QObject3";
+ auto package{createSimpleSynchronizationPackage()};
+ package.types[0].prototype = Storage::ImportedType{"Object"};
+ package.types[0].propertyDeclarations[0].typeName = Storage::ImportedType{"Object"};
+ storage.synchronize(package);
+ package.types[1].exportedTypes[0].moduleId = qtQuickModuleId;
+ package.types[1].exportedTypes[1].moduleId = qtQuickModuleId;
+ package.types[1].exportedTypes[2].moduleId = qtQuickModuleId;
+ package.types[1].exportedTypes[2].name = "QObject3";
+ package.types[1].typeName = "QObject3";
- storage.synchronize({}, importsSourceId2, {types[1]}, {sourceId2}, {});
+ storage.synchronize(SynchronizationPackage{importsSourceId2, {package.types[1]}, {sourceId2}});
ASSERT_THAT(storage.fetchTypes(),
- Contains(IsStorageType(qtQuickModuleId,
+ Contains(IsStorageType(sourceId1,
"QQuickItem",
- Storage::NativeType{"QObject3"},
- TypeAccessSemantics::Reference,
- sourceId1)));
+ fetchTypeId(sourceId2, "QObject3"),
+ TypeAccessSemantics::Reference)));
}
TEST_F(ProjectStorage, ChangePrototypeTypeNameThrowsForWrongNativePrototupeTypeName)
{
- Storage::Types types{createTypes()};
- types[0].propertyDeclarations[0].typeName = Storage::ImportedType{"Object"};
- storage.synchronize(
- modules,
- imports,
- types,
- {sourceId1, sourceId2, qmlModuleSourceId, qtQuickModuleSourceId, pathToModuleSourceId},
- {});
- types[1].typeName = "QObject3";
-
- ASSERT_THROW(storage.synchronize({}, importsSourceId2, {types[1]}, {sourceId2}, {}),
+ auto package{createSimpleSynchronizationPackage()};
+ package.types[0].propertyDeclarations[0].typeName = Storage::ImportedType{"Object"};
+ storage.synchronize(package);
+ package.types[1].exportedTypes[2].name = "QObject3";
+ package.types[1].typeName = "QObject3";
+
+ ASSERT_THROW(storage.synchronize(
+ SynchronizationPackage{importsSourceId2, {package.types[1]}, {sourceId2}}),
QmlDesigner::TypeNameDoesNotExists);
}
TEST_F(ProjectStorage, ThrowForPrototypeChainCycles)
{
- Storage::Types types{createTypes()};
- types[1].prototype = Storage::ImportedType{"Object2"};
- types.push_back(Storage::Type{pathToModuleId,
- "QObject2",
- Storage::ImportedType{"Item"},
- TypeAccessSemantics::Reference,
- sourceId3,
- {Storage::ExportedType{"Object2"}, Storage::ExportedType{"Obj2"}}});
- imports.emplace_back("/path/to", Storage::Version{}, sourceId2);
- imports.emplace_back("QtQuick", Storage::Version{}, sourceId3);
- imports.emplace_back("/path/to", Storage::Version{}, sourceId3);
-
- ASSERT_THROW(storage.synchronize(modules,
- imports,
- types,
- {sourceId1,
- sourceId2,
- sourceId3,
- qmlModuleSourceId,
- qtQuickModuleSourceId,
- pathToModuleSourceId},
- {}),
+ auto package{createSimpleSynchronizationPackage()};
+ package.types[1].prototype = Storage::ImportedType{"Object2"};
+ package.types.push_back(Storage::Type{"QObject2",
+ Storage::ImportedType{"Item"},
+ TypeAccessSemantics::Reference,
+ sourceId3,
+ {Storage::ExportedType{pathToModuleId, "Object2"},
+ Storage::ExportedType{pathToModuleId, "Obj2"}}});
+ package.imports.emplace_back(pathToModuleId, Storage::Version{}, sourceId2);
+ package.imports.emplace_back(qtQuickModuleId, Storage::Version{}, sourceId3);
+ package.imports.emplace_back(pathToModuleId, Storage::Version{}, sourceId3);
+
+ ASSERT_THROW(storage.synchronize(SynchronizationPackage{package.imports,
+ package.types,
+ {sourceId1, sourceId2, sourceId3}}),
QmlDesigner::PrototypeChainCycle);
}
TEST_F(ProjectStorage, ThrowForTypeIdAndPrototypeIdAreTheSame)
{
- Storage::Types types{createTypes()};
- types[1].prototype = Storage::ImportedType{"Object"};
-
- ASSERT_THROW(storage.synchronize(modules,
- imports,
- types,
- {sourceId1,
- sourceId2,
- qmlModuleSourceId,
- qtQuickModuleSourceId,
- pathToModuleSourceId},
- {}),
- QmlDesigner::PrototypeChainCycle);
+ auto package{createSimpleSynchronizationPackage()};
+ package.types[1].prototype = Storage::ImportedType{"Object"};
+
+ ASSERT_THROW(storage.synchronize(package), QmlDesigner::PrototypeChainCycle);
}
TEST_F(ProjectStorage, ThrowForTypeIdAndPrototypeIdAreTheSameForRelinking)
{
- Storage::Types types{createTypesWithExportedTypeNamesOnly()};
- storage.synchronize(
- modules,
- imports,
- types,
- {sourceId1, sourceId2, qmlModuleSourceId, qtQuickModuleSourceId, pathToModuleSourceId},
- {});
- types[1].prototype = Storage::ImportedType{"Item"};
- types[1].typeName = "QObject2";
- importsSourceId2.emplace_back("QtQuick", Storage::Version{}, sourceId2);
-
- ASSERT_THROW(storage.synchronize({}, importsSourceId2, {types[1]}, {sourceId2}, {}),
+ auto package{createSimpleSynchronizationPackage()};
+ storage.synchronize(package);
+ package.types[1].prototype = Storage::ImportedType{"Item"};
+ package.types[1].typeName = "QObject2";
+ importsSourceId2.emplace_back(qtQuickModuleId, Storage::Version{}, sourceId2);
+
+ ASSERT_THROW(storage.synchronize(
+ SynchronizationPackage{importsSourceId2, {package.types[1]}, {sourceId2}}),
QmlDesigner::PrototypeChainCycle);
}
TEST_F(ProjectStorage, RecursiveAliases)
{
- Storage::Types types{createTypesWithRecursiveAliases()};
-
- storage.synchronize(modules,
- imports,
- types,
- {sourceId1,
- sourceId2,
- sourceId3,
- sourceId4,
- sourceId5,
- qmlModuleSourceId,
- qtQuickModuleSourceId,
- pathToModuleSourceId},
- {});
+ auto package{createSynchronizationPackageWithRecursiveAliases()};
+
+ storage.synchronize(package);
ASSERT_THAT(storage.fetchTypes(),
- Contains(AllOf(IsStorageType(qtQuickModuleId,
+ Contains(AllOf(IsStorageType(sourceId5,
"QAliasItem2",
- Storage::NativeType{"QObject"},
- TypeAccessSemantics::Reference,
- sourceId5),
+ fetchTypeId(sourceId2, "QObject"),
+ TypeAccessSemantics::Reference),
Field(&Storage::Type::propertyDeclarations,
ElementsAre(IsPropertyDeclaration(
"objects",
- Storage::NativeType{"QObject"},
+ fetchTypeId(sourceId2, "QObject"),
Storage::PropertyDeclarationTraits::IsList))))));
}
TEST_F(ProjectStorage, RecursiveAliasesChangePropertyType)
{
- Storage::Types types{createTypesWithRecursiveAliases()};
- storage.synchronize(modules,
- imports,
- types,
- {sourceId1,
- sourceId2,
- sourceId3,
- sourceId4,
- sourceId5,
- qmlModuleSourceId,
- qtQuickModuleSourceId,
- pathToModuleSourceId},
- {});
- types[1].propertyDeclarations[0].typeName = Storage::ImportedType{"Object2"};
- importsSourceId2.emplace_back("/path/to", Storage::Version{}, sourceId2);
-
- storage.synchronize({}, importsSourceId2, {types[1]}, {sourceId2}, {});
+ auto package{createSynchronizationPackageWithRecursiveAliases()};
+ storage.synchronize(package);
+ package.types[1].propertyDeclarations[0].typeName = Storage::ImportedType{"Object2"};
+ importsSourceId2.emplace_back(pathToModuleId, Storage::Version{}, sourceId2);
+
+ storage.synchronize(SynchronizationPackage{importsSourceId2, {package.types[1]}, {sourceId2}});
ASSERT_THAT(storage.fetchTypes(),
- Contains(AllOf(IsStorageType(qtQuickModuleId,
+ Contains(AllOf(IsStorageType(sourceId5,
"QAliasItem2",
- Storage::NativeType{"QObject"},
- TypeAccessSemantics::Reference,
- sourceId5),
+ fetchTypeId(sourceId2, "QObject"),
+ TypeAccessSemantics::Reference),
Field(&Storage::Type::propertyDeclarations,
ElementsAre(IsPropertyDeclaration(
"objects",
- Storage::NativeType{"QObject2"},
+ fetchTypeId(sourceId4, "QObject2"),
Storage::PropertyDeclarationTraits::IsList))))));
}
TEST_F(ProjectStorage, UpdateAliasesAfterInjectingProperty)
{
- Storage::Types types{createTypesWithRecursiveAliases()};
- storage.synchronize(modules,
- imports,
- types,
- {sourceId1,
- sourceId2,
- sourceId3,
- sourceId4,
- sourceId5,
- qmlModuleSourceId,
- qtQuickModuleSourceId,
- pathToModuleSourceId},
- {});
- types[0].propertyDeclarations.push_back(
+ auto package{createSynchronizationPackageWithRecursiveAliases()};
+ storage.synchronize(package);
+ package.types[0].propertyDeclarations.push_back(
Storage::PropertyDeclaration{"objects",
Storage::ImportedType{"Item"},
Storage::PropertyDeclarationTraits::IsList
| Storage::PropertyDeclarationTraits::IsReadOnly});
- storage.synchronize({}, importsSourceId1, {types[0]}, {sourceId1}, {});
+ storage.synchronize(SynchronizationPackage{importsSourceId1, {package.types[0]}, {sourceId1}});
ASSERT_THAT(storage.fetchTypes(),
- Contains(AllOf(IsStorageType(qtQuickModuleId,
+ Contains(AllOf(IsStorageType(sourceId5,
"QAliasItem2",
- Storage::NativeType{"QObject"},
- TypeAccessSemantics::Reference,
- sourceId5),
+ fetchTypeId(sourceId2, "QObject"),
+ TypeAccessSemantics::Reference),
Field(&Storage::Type::propertyDeclarations,
ElementsAre(IsPropertyDeclaration(
"objects",
- Storage::NativeType{"QQuickItem"},
+ fetchTypeId(sourceId1, "QQuickItem"),
Storage::PropertyDeclarationTraits::IsList
| Storage::PropertyDeclarationTraits::IsReadOnly))))));
}
TEST_F(ProjectStorage, UpdateAliasesAfterChangeAliasToProperty)
{
- Storage::Types types{createTypesWithRecursiveAliases()};
- storage.synchronize(modules,
- imports,
- types,
- {sourceId1,
- sourceId2,
- sourceId3,
- sourceId4,
- sourceId5,
- qmlModuleSourceId,
- qtQuickModuleSourceId,
- pathToModuleSourceId},
- {});
- types[2].propertyDeclarations.clear();
- types[2].propertyDeclarations.push_back(
+ auto package{createSynchronizationPackageWithRecursiveAliases()};
+ storage.synchronize(package);
+ package.types[2].propertyDeclarations.clear();
+ package.types[2].propertyDeclarations.push_back(
Storage::PropertyDeclaration{"objects",
Storage::ImportedType{"Item"},
Storage::PropertyDeclarationTraits::IsList
| Storage::PropertyDeclarationTraits::IsReadOnly});
- storage.synchronize({}, importsSourceId3, {types[2]}, {sourceId3}, {});
+ storage.synchronize(SynchronizationPackage{importsSourceId3, {package.types[2]}, {sourceId3}});
ASSERT_THAT(storage.fetchTypes(),
- AllOf(Contains(AllOf(IsStorageType(qtQuickModuleId,
+ AllOf(Contains(AllOf(IsStorageType(sourceId5,
"QAliasItem2",
- Storage::NativeType{"QObject"},
- TypeAccessSemantics::Reference,
- sourceId5),
+ fetchTypeId(sourceId2, "QObject"),
+ TypeAccessSemantics::Reference),
Field(&Storage::Type::propertyDeclarations,
ElementsAre(IsPropertyDeclaration(
"objects",
- Storage::NativeType{"QQuickItem"},
+ fetchTypeId(sourceId1, "QQuickItem"),
Storage::PropertyDeclarationTraits::IsList
| Storage::PropertyDeclarationTraits::IsReadOnly,
"objects"))))),
- Contains(AllOf(IsStorageType(qtQuickModuleId,
+ Contains(AllOf(IsStorageType(sourceId3,
"QAliasItem",
- Storage::NativeType{"QQuickItem"},
- TypeAccessSemantics::Reference,
- sourceId3),
+ fetchTypeId(sourceId1, "QQuickItem"),
+ TypeAccessSemantics::Reference),
Field(&Storage::Type::propertyDeclarations,
ElementsAre(IsPropertyDeclaration(
"objects",
- Storage::NativeType{"QQuickItem"},
+ fetchTypeId(sourceId1, "QQuickItem"),
Storage::PropertyDeclarationTraits::IsList
| Storage::PropertyDeclarationTraits::IsReadOnly,
"")))))));
@@ -3764,38 +2786,26 @@ TEST_F(ProjectStorage, UpdateAliasesAfterChangeAliasToProperty)
TEST_F(ProjectStorage, UpdateAliasesAfterChangePropertyToAlias)
{
- Storage::Types types{createTypesWithRecursiveAliases()};
- types[3].propertyDeclarations[0].traits = Storage::PropertyDeclarationTraits::IsList
- | Storage::PropertyDeclarationTraits::IsReadOnly;
- storage.synchronize(modules,
- imports,
- types,
- {sourceId1,
- sourceId2,
- sourceId3,
- sourceId4,
- sourceId5,
- qmlModuleSourceId,
- qtQuickModuleSourceId,
- pathToModuleSourceId},
- {});
- types[1].propertyDeclarations.clear();
- types[1].propertyDeclarations.push_back(
+ auto package{createSynchronizationPackageWithRecursiveAliases()};
+ package.types[3].propertyDeclarations[0].traits = Storage::PropertyDeclarationTraits::IsList
+ | Storage::PropertyDeclarationTraits::IsReadOnly;
+ storage.synchronize(package);
+ package.types[1].propertyDeclarations.clear();
+ package.types[1].propertyDeclarations.push_back(
Storage::PropertyDeclaration{"objects", Storage::ImportedType{"Object2"}, "objects"});
- importsSourceId2.emplace_back("/path/to", Storage::Version{}, sourceId2);
+ importsSourceId2.emplace_back(pathToModuleId, Storage::Version{}, sourceId2);
- storage.synchronize({}, importsSourceId2, {types[1]}, {sourceId2}, {});
+ storage.synchronize(SynchronizationPackage{importsSourceId2, {package.types[1]}, {sourceId2}});
ASSERT_THAT(storage.fetchTypes(),
- Contains(AllOf(IsStorageType(qtQuickModuleId,
+ Contains(AllOf(IsStorageType(sourceId5,
"QAliasItem2",
- Storage::NativeType{"QObject"},
- TypeAccessSemantics::Reference,
- sourceId5),
+ fetchTypeId(sourceId2, "QObject"),
+ TypeAccessSemantics::Reference),
Field(&Storage::Type::propertyDeclarations,
ElementsAre(IsPropertyDeclaration(
"objects",
- Storage::NativeType{"QObject"},
+ fetchTypeId(sourceId2, "QObject"),
Storage::PropertyDeclarationTraits::IsList
| Storage::PropertyDeclarationTraits::IsReadOnly,
"objects"))))));
@@ -3803,379 +2813,270 @@ TEST_F(ProjectStorage, UpdateAliasesAfterChangePropertyToAlias)
TEST_F(ProjectStorage, CheckForProtoTypeCycleThrows)
{
- Storage::Types types{createTypesWithRecursiveAliases()};
- types[1].propertyDeclarations.clear();
- types[1].propertyDeclarations.push_back(
+ auto package{createSynchronizationPackageWithRecursiveAliases()};
+ package.types[1].propertyDeclarations.clear();
+ package.types[1].propertyDeclarations.push_back(
Storage::PropertyDeclaration{"objects", Storage::ImportedType{"AliasItem2"}, "objects"});
- imports.emplace_back("QtQuick", Storage::Version{}, sourceId2);
-
- ASSERT_THROW(storage.synchronize(modules,
- imports,
- types,
- {sourceId1,
- sourceId2,
- sourceId3,
- sourceId4,
- sourceId5,
- qmlModuleSourceId,
- qtQuickModuleSourceId,
- pathToModuleSourceId},
- {}),
- QmlDesigner::AliasChainCycle);
+ package.imports.emplace_back(qtQuickModuleId, Storage::Version{}, sourceId2);
+
+ ASSERT_THROW(storage.synchronize(package), QmlDesigner::AliasChainCycle);
}
TEST_F(ProjectStorage, CheckForProtoTypeCycleAfterUpdateThrows)
{
- Storage::Types types{createTypesWithRecursiveAliases()};
- storage.synchronize(modules,
- imports,
- types,
- {sourceId1,
- sourceId2,
- sourceId3,
- sourceId4,
- sourceId5,
- qmlModuleSourceId,
- qtQuickModuleSourceId,
- pathToModuleSourceId},
- {});
- types[1].propertyDeclarations.clear();
- types[1].propertyDeclarations.push_back(
+ auto package{createSynchronizationPackageWithRecursiveAliases()};
+ storage.synchronize(package);
+ package.types[1].propertyDeclarations.clear();
+ package.types[1].propertyDeclarations.push_back(
Storage::PropertyDeclaration{"objects", Storage::ImportedType{"AliasItem2"}, "objects"});
- importsSourceId2.emplace_back("QtQuick", Storage::Version{}, sourceId2);
+ importsSourceId2.emplace_back(qtQuickModuleId, Storage::Version{}, sourceId2);
- ASSERT_THROW(storage.synchronize({}, importsSourceId2, {types[1]}, {sourceId2}, {}),
+ ASSERT_THROW(storage.synchronize(
+ SynchronizationPackage{importsSourceId2, {package.types[1]}, {sourceId2}}),
QmlDesigner::AliasChainCycle);
}
TEST_F(ProjectStorage, QualifiedPrototype)
{
- Storage::Types types{createTypes()};
- types[0].prototype = Storage::QualifiedImportedType{"Object",
- Storage::Import{"Qml",
- Storage::Version{},
- sourceId1}};
- types.push_back(Storage::Type{qtQuickModuleId,
- "QQuickObject",
- Storage::NativeType{},
- TypeAccessSemantics::Reference,
- sourceId3,
- {Storage::ExportedType{"Object"}}});
- imports.emplace_back("QtQuick", Storage::Version{}, sourceId3);
+ auto package{createSimpleSynchronizationPackage()};
+ package.types[0].prototype = Storage::QualifiedImportedType{"Object",
+ Storage::Import{qmlModuleId,
+ Storage::Version{},
+ sourceId1}};
+ package.types.push_back(Storage::Type{"QQuickObject",
+ Storage::ImportedType{},
+ TypeAccessSemantics::Reference,
+ sourceId3,
+ {Storage::ExportedType{qtQuickModuleId, "Object"}}});
+ package.imports.emplace_back(qtQuickModuleId, Storage::Version{}, sourceId3);
+ package.sourceIds.push_back(sourceId3);
- storage.synchronize(
- modules,
- imports,
- types,
- {sourceId1, sourceId2, sourceId3, qmlModuleSourceId, qtQuickModuleSourceId, pathToModuleSourceId},
- {});
+ storage.synchronize(package);
ASSERT_THAT(storage.fetchTypes(),
- Contains(IsStorageType(qtQuickModuleId,
+ Contains(IsStorageType(sourceId1,
"QQuickItem",
- Storage::NativeType{"QObject"},
- TypeAccessSemantics::Reference,
- sourceId1)));
+ fetchTypeId(sourceId2, "QObject"),
+ TypeAccessSemantics::Reference)));
}
TEST_F(ProjectStorage, QualifiedPrototypeUpperDownTheModuleChainThrows)
{
- Storage::Types types{createTypes()};
- types[0].prototype = Storage::QualifiedImportedType{"Object",
- Storage::Import{"QtQuick",
- Storage::Version{},
- sourceId1}};
-
- ASSERT_THROW(storage.synchronize(modules,
- imports,
- types,
- {sourceId1,
- sourceId2,
- qmlModuleSourceId,
- qtQuickModuleSourceId,
- pathToModuleSourceId},
- {}),
- QmlDesigner::TypeNameDoesNotExists);
+ auto package{createSimpleSynchronizationPackage()};
+ package.types[0].prototype = Storage::QualifiedImportedType{"Object",
+ Storage::Import{qtQuickModuleId,
+ Storage::Version{},
+ sourceId1}};
+
+ ASSERT_THROW(storage.synchronize(package), QmlDesigner::TypeNameDoesNotExists);
}
TEST_F(ProjectStorage, QualifiedPrototypeUpperInTheModuleChain)
{
- Storage::Types types{createTypes()};
- types[0].prototype = Storage::QualifiedImportedType{"Object",
- Storage::Import{"QtQuick",
- Storage::Version{},
- sourceId1}};
- types.push_back(Storage::Type{qtQuickModuleId,
- "QQuickObject",
- Storage::NativeType{},
- TypeAccessSemantics::Reference,
- sourceId3,
- {Storage::ExportedType{"Object"}}});
- imports.emplace_back("QtQuick", Storage::Version{}, sourceId3);
+ auto package{createSimpleSynchronizationPackage()};
+ package.types[0].prototype = Storage::QualifiedImportedType{"Object",
+ Storage::Import{qtQuickModuleId,
+ Storage::Version{},
+ sourceId1}};
+ package.types.push_back(Storage::Type{"QQuickObject",
+ Storage::ImportedType{},
+ TypeAccessSemantics::Reference,
+ sourceId3,
+ {Storage::ExportedType{qtQuickModuleId, "Object"}}});
+ package.imports.emplace_back(qtQuickModuleId, Storage::Version{}, sourceId3);
+ package.sourceIds.push_back(sourceId3);
- storage.synchronize(
- modules,
- imports,
- types,
- {sourceId1, sourceId2, sourceId3, qmlModuleSourceId, qtQuickModuleSourceId, pathToModuleSourceId},
- {});
+ storage.synchronize(package);
ASSERT_THAT(storage.fetchTypes(),
- Contains(IsStorageType(qtQuickModuleId,
+ Contains(IsStorageType(sourceId1,
"QQuickItem",
- Storage::NativeType{"QQuickObject"},
- TypeAccessSemantics::Reference,
- sourceId1)));
+ fetchTypeId(sourceId3, "QQuickObject"),
+ TypeAccessSemantics::Reference)));
}
TEST_F(ProjectStorage, QualifiedPrototypeWithWrongVersionThrows)
{
- Storage::Types types{createTypes()};
- types[0].prototype = Storage::QualifiedImportedType{"Object",
- Storage::Import{"Qml",
- Storage::Version{4},
- sourceId1}};
- types.push_back(Storage::Type{qtQuickModuleId,
- "QQuickObject",
- Storage::NativeType{},
- TypeAccessSemantics::Reference,
- sourceId3,
- {Storage::ExportedType{"Object"}}});
- imports.emplace_back("QtQuick", Storage::Version{}, sourceId3);
-
- ASSERT_THROW(storage.synchronize(modules,
- imports,
- types,
- {sourceId1,
- sourceId2,
- sourceId3,
- qmlModuleSourceId,
- qtQuickModuleSourceId,
- pathToModuleSourceId},
- {}),
- QmlDesigner::TypeNameDoesNotExists);
+ auto package{createSimpleSynchronizationPackage()};
+ package.types[0].prototype = Storage::QualifiedImportedType{"Object",
+ Storage::Import{qmlModuleId,
+ Storage::Version{4},
+ sourceId1}};
+ package.types.push_back(Storage::Type{"QQuickObject",
+ Storage::ImportedType{},
+ TypeAccessSemantics::Reference,
+ sourceId3,
+ {Storage::ExportedType{qtQuickModuleId, "Object"}}});
+ package.imports.emplace_back(qtQuickModuleId, Storage::Version{}, sourceId3);
+ package.sourceIds.push_back(sourceId3);
+
+ ASSERT_THROW(storage.synchronize(package), QmlDesigner::TypeNameDoesNotExists);
}
TEST_F(ProjectStorage, QualifiedPrototypeWithVersion)
{
- Storage::Types types{createTypes()};
- imports[0].version = Storage::Version{2};
- types[0].prototype = Storage::QualifiedImportedType{"Object", imports[0]};
- types.push_back(Storage::Type{qtQuickModuleId,
- "QQuickObject",
- Storage::NativeType{},
- TypeAccessSemantics::Reference,
- sourceId3,
- {Storage::ExportedType{"Object"}}});
- imports.emplace_back("QtQuick", Storage::Version{}, sourceId3);
+ auto package{createSimpleSynchronizationPackage()};
+ package.imports[0].version = Storage::Version{2};
+ package.types[0].prototype = Storage::QualifiedImportedType{"Object", package.imports[0]};
+ package.types.push_back(Storage::Type{"QQuickObject",
+ Storage::ImportedType{},
+ TypeAccessSemantics::Reference,
+ sourceId3,
+ {Storage::ExportedType{qtQuickModuleId, "Object"}}});
+ package.imports.emplace_back(qtQuickModuleId, Storage::Version{}, sourceId3);
+ package.sourceIds.push_back(sourceId3);
- storage.synchronize(
- modules,
- imports,
- types,
- {sourceId1, sourceId2, sourceId3, qmlModuleSourceId, qtQuickModuleSourceId, pathToModuleSourceId},
- {});
+ storage.synchronize(package);
ASSERT_THAT(storage.fetchTypes(),
- Contains(IsStorageType(qtQuickModuleId,
+ Contains(IsStorageType(sourceId1,
"QQuickItem",
- Storage::NativeType{"QObject"},
- TypeAccessSemantics::Reference,
- sourceId1)));
+ fetchTypeId(sourceId2, "QObject"),
+ TypeAccessSemantics::Reference)));
}
TEST_F(ProjectStorage, QualifiedPrototypeWithVersionInTheProtoTypeChain)
{
- Storage::Types types{createTypes()};
- imports[2].version = Storage::Version{2};
- types[0].prototype = Storage::QualifiedImportedType{"Object", imports[2]};
- types[0].exportedTypes[0].version = Storage::Version{2};
- types.push_back(Storage::Type{qtQuickModuleId,
- "QQuickObject",
- Storage::NativeType{},
- TypeAccessSemantics::Reference,
- sourceId3,
- {Storage::ExportedType{"Object", Storage::Version{2}}}});
- imports.emplace_back("QtQuick", Storage::Version{}, sourceId3);
+ auto package{createSimpleSynchronizationPackage()};
+ package.imports[2].version = Storage::Version{2};
+ package.types[0].prototype = Storage::QualifiedImportedType{"Object", package.imports[2]};
+ package.types[0].exportedTypes[0].version = Storage::Version{2};
+ package.types.push_back(
+ Storage::Type{"QQuickObject",
+ Storage::ImportedType{},
+ TypeAccessSemantics::Reference,
+ sourceId3,
+ {Storage::ExportedType{qtQuickModuleId, "Object", Storage::Version{2}}}});
+ package.imports.emplace_back(qtQuickModuleId, Storage::Version{}, sourceId3);
+ package.sourceIds.push_back(sourceId3);
- storage.synchronize(
- modules,
- imports,
- types,
- {sourceId1, sourceId2, sourceId3, qmlModuleSourceId, qtQuickModuleSourceId, pathToModuleSourceId},
- {});
+ storage.synchronize(package);
ASSERT_THAT(storage.fetchTypes(),
- Contains(IsStorageType(qtQuickModuleId,
+ Contains(IsStorageType(sourceId1,
"QQuickItem",
- Storage::NativeType{"QQuickObject"},
- TypeAccessSemantics::Reference,
- sourceId1)));
+ fetchTypeId(sourceId3, "QQuickObject"),
+ TypeAccessSemantics::Reference)));
}
TEST_F(ProjectStorage, QualifiedPrototypeWithVersionDownTheProtoTypeChainThrows)
{
- Storage::Types types{createTypes()};
- types[0].prototype = Storage::QualifiedImportedType{"Object",
- Storage::Import{"QtQuick",
- Storage::Version{2},
- sourceId1}};
-
- ASSERT_THROW(storage.synchronize(modules,
- imports,
- types,
- {sourceId1,
- sourceId2,
- sourceId3,
- qmlModuleSourceId,
- qtQuickModuleSourceId,
- pathToModuleSourceId},
- {}),
- QmlDesigner::TypeNameDoesNotExists);
+ auto package{createSimpleSynchronizationPackage()};
+ package.types[0].prototype = Storage::QualifiedImportedType{"Object",
+ Storage::Import{qtQuickModuleId,
+ Storage::Version{2},
+ sourceId1}};
+
+ ASSERT_THROW(storage.synchronize(package), QmlDesigner::TypeNameDoesNotExists);
}
TEST_F(ProjectStorage, QualifiedPropertyDeclarationTypeName)
{
- Storage::Types types{createTypes()};
- types[0].propertyDeclarations[0].typeName = Storage::QualifiedImportedType{
- "Object", Storage::Import{"Qml", Storage::Version{}, sourceId1}};
- types.push_back(Storage::Type{qtQuickModuleId,
- "QQuickObject",
- Storage::NativeType{},
- TypeAccessSemantics::Reference,
- sourceId3,
- {Storage::ExportedType{"Object"}}});
- imports.emplace_back("QtQuick", Storage::Version{}, sourceId3);
+ auto package{createSimpleSynchronizationPackage()};
+ package.types[0].propertyDeclarations[0].typeName = Storage::QualifiedImportedType{
+ "Object", Storage::Import{qmlModuleId, Storage::Version{}, sourceId1}};
+ package.types.push_back(Storage::Type{"QQuickObject",
+ Storage::ImportedType{},
+ TypeAccessSemantics::Reference,
+ sourceId3,
+ {Storage::ExportedType{qtQuickModuleId, "Object"}}});
+ package.imports.emplace_back(qtQuickModuleId, Storage::Version{}, sourceId3);
+ package.sourceIds.push_back(sourceId3);
- storage.synchronize(
- modules,
- imports,
- types,
- {sourceId1, sourceId2, sourceId3, qmlModuleSourceId, qtQuickModuleSourceId, pathToModuleSourceId},
- {});
+ storage.synchronize(package);
ASSERT_THAT(storage.fetchTypes(),
Contains(
Field(&Storage::Type::propertyDeclarations,
Contains(IsPropertyDeclaration("data",
- Storage::NativeType{"QObject"},
+ fetchTypeId(sourceId2, "QObject"),
Storage::PropertyDeclarationTraits::IsList)))));
}
TEST_F(ProjectStorage, QualifiedPropertyDeclarationTypeNameDownTheModuleChainThrows)
{
- Storage::Types types{createTypes()};
- types[0].propertyDeclarations[0].typeName = Storage::QualifiedImportedType{
- "Object", Storage::Import{"QtQuick", Storage::Version{}, sourceId1}};
-
- ASSERT_THROW(storage.synchronize(modules,
- imports,
- types,
- {sourceId1,
- sourceId2,
- sourceId3,
- qmlModuleSourceId,
- qtQuickModuleSourceId,
- pathToModuleSourceId},
- {}),
- QmlDesigner::TypeNameDoesNotExists);
+ auto package{createSimpleSynchronizationPackage()};
+ package.types[0].propertyDeclarations[0].typeName = Storage::QualifiedImportedType{
+ "Object", Storage::Import{qtQuickModuleId, Storage::Version{}, sourceId1}};
+
+ ASSERT_THROW(storage.synchronize(package), QmlDesigner::TypeNameDoesNotExists);
}
TEST_F(ProjectStorage, QualifiedPropertyDeclarationTypeNameInTheModuleChain)
{
- Storage::Types types{createTypes()};
- types[0].propertyDeclarations[0].typeName = Storage::QualifiedImportedType{
- "Object", Storage::Import{"QtQuick", Storage::Version{}, sourceId1}};
- types.push_back(Storage::Type{qtQuickModuleId,
- "QQuickObject",
- Storage::NativeType{},
- TypeAccessSemantics::Reference,
- sourceId3,
- {Storage::ExportedType{"Object"}}});
- imports.emplace_back("QtQuick", Storage::Version{}, sourceId3);
+ auto package{createSimpleSynchronizationPackage()};
+ package.types[0].propertyDeclarations[0].typeName = Storage::QualifiedImportedType{
+ "Object", Storage::Import{qtQuickModuleId, Storage::Version{}, sourceId1}};
+ package.types.push_back(Storage::Type{"QQuickObject",
+ Storage::ImportedType{},
+ TypeAccessSemantics::Reference,
+ sourceId3,
+ {Storage::ExportedType{qtQuickModuleId, "Object"}}});
+ package.imports.emplace_back(qtQuickModuleId, Storage::Version{}, sourceId3);
+ package.sourceIds.push_back(sourceId3);
- storage.synchronize(
- modules,
- imports,
- types,
- {sourceId1, sourceId2, sourceId3, qmlModuleSourceId, qtQuickModuleSourceId, pathToModuleSourceId},
- {});
+ storage.synchronize(package);
ASSERT_THAT(storage.fetchTypes(),
Contains(
Field(&Storage::Type::propertyDeclarations,
Contains(IsPropertyDeclaration("data",
- Storage::NativeType{"QQuickObject"},
+ fetchTypeId(sourceId3, "QQuickObject"),
Storage::PropertyDeclarationTraits::IsList)))));
}
TEST_F(ProjectStorage, QualifiedPropertyDeclarationTypeNameWithVersion)
{
- Storage::Types types{createTypes()};
- types[0].propertyDeclarations[0].typeName = Storage::QualifiedImportedType{
- "Object", Storage::Import{"Qml", Storage::Version{2}, sourceId1}};
- imports.emplace_back("Qml", Storage::Version{2}, sourceId1);
+ auto package{createSimpleSynchronizationPackage()};
+ package.types[0].propertyDeclarations[0].typeName = Storage::QualifiedImportedType{
+ "Object", Storage::Import{qmlModuleId, Storage::Version{2}, sourceId1}};
+ package.imports.emplace_back(qmlModuleId, Storage::Version{2}, sourceId1);
- storage.synchronize(
- modules,
- imports,
- types,
- {sourceId1, sourceId2, qmlModuleSourceId, qtQuickModuleSourceId, pathToModuleSourceId},
- {});
+ storage.synchronize(package);
ASSERT_THAT(storage.fetchTypes(),
Contains(
Field(&Storage::Type::propertyDeclarations,
Contains(IsPropertyDeclaration("data",
- Storage::NativeType{"QObject"},
+ fetchTypeId(sourceId2, "QObject"),
Storage::PropertyDeclarationTraits::IsList)))));
}
TEST_F(ProjectStorage, ChangePropertyTypeModuleIdWithQualifiedTypeThrows)
{
- Storage::Types types{createTypes()};
- types[0].propertyDeclarations[0].typeName = Storage::QualifiedImportedType{
- "Object", Storage::Import{"Qml", Storage::Version{}, sourceId1}};
- storage.synchronize(
- modules,
- imports,
- types,
- {sourceId1, sourceId2, qmlModuleSourceId, qtQuickModuleSourceId, pathToModuleSourceId},
- {});
- types[1].moduleId = qtQuickModuleId;
-
- ASSERT_THROW(storage.synchronize({}, importsSourceId2, {types[1]}, {sourceId2}, {}),
+ auto package{createSimpleSynchronizationPackage()};
+ package.types[0].propertyDeclarations[0].typeName = Storage::QualifiedImportedType{
+ "Object", Storage::Import{qmlModuleId, Storage::Version{}, sourceId1}};
+ storage.synchronize(package);
+ package.types[1].exportedTypes[0].moduleId = qtQuickModuleId;
+
+ ASSERT_THROW(storage.synchronize(
+ SynchronizationPackage{importsSourceId2, {package.types[1]}, {sourceId2}}),
QmlDesigner::TypeNameDoesNotExists);
}
TEST_F(ProjectStorage, ChangePropertyTypeModuleIdWithQualifiedType)
{
- Storage::Types types{createTypes()};
- types[0].propertyDeclarations[0].typeName = Storage::QualifiedImportedType{
- "Object", Storage::Import{"Qml", Storage::Version{}, sourceId1}};
- storage.synchronize(
- modules,
- imports,
- types,
- {sourceId1, sourceId2, qmlModuleSourceId, qtQuickModuleSourceId, pathToModuleSourceId},
- {});
- types[0].propertyDeclarations[0].typeName = Storage::QualifiedImportedType{
- "Object", Storage::Import{"QtQuick", Storage::Version{}, sourceId1}};
- types[1].moduleId = qtQuickModuleId;
- imports.emplace_back("QtQuick", Storage::Version{}, sourceId2);
-
- storage.synchronize({}, imports, types, {sourceId1, sourceId2}, {});
+ auto package{createSimpleSynchronizationPackage()};
+ package.types[0].propertyDeclarations[0].typeName = Storage::QualifiedImportedType{
+ "Object", Storage::Import{qmlModuleId, Storage::Version{}, sourceId1}};
+ storage.synchronize(package);
+ package.types[0].propertyDeclarations[0].typeName = Storage::QualifiedImportedType{
+ "Object", Storage::Import{qtQuickModuleId, Storage::Version{}, sourceId1}};
+ package.types[1].exportedTypes[0].moduleId = qtQuickModuleId;
+ package.imports.emplace_back(qtQuickModuleId, Storage::Version{}, sourceId2);
+
+ storage.synchronize(package);
ASSERT_THAT(storage.fetchTypes(),
- Contains(AllOf(IsStorageType(qtQuickModuleId,
+ Contains(AllOf(IsStorageType(sourceId1,
"QQuickItem",
- Storage::NativeType{"QObject"},
- TypeAccessSemantics::Reference,
- sourceId1),
+ fetchTypeId(sourceId2, "QObject"),
+ TypeAccessSemantics::Reference),
Field(&Storage::Type::propertyDeclarations,
Contains(IsPropertyDeclaration(
"data",
- Storage::NativeType{"QObject"},
+ fetchTypeId(sourceId2, "QObject"),
Storage::PropertyDeclarationTraits::IsList))))));
}
@@ -4184,7 +3085,7 @@ TEST_F(ProjectStorage, AddFileStatuses)
FileStatus fileStatus1{sourceId1, 100, 100};
FileStatus fileStatus2{sourceId2, 101, 101};
- storage.synchronize({}, {}, {}, {sourceId1, sourceId2}, {fileStatus1, fileStatus2});
+ storage.synchronize(SynchronizationPackage{{sourceId1, sourceId2}, {fileStatus1, fileStatus2}});
ASSERT_THAT(convert(storage.fetchAllFileStatuses()),
UnorderedElementsAre(fileStatus1, fileStatus2));
@@ -4194,9 +3095,9 @@ TEST_F(ProjectStorage, RemoveFileStatus)
{
FileStatus fileStatus1{sourceId1, 100, 100};
FileStatus fileStatus2{sourceId2, 101, 101};
- storage.synchronize({}, {}, {}, {sourceId1, sourceId2}, {fileStatus1, fileStatus2});
+ storage.synchronize(SynchronizationPackage{{sourceId1, sourceId2}, {fileStatus1, fileStatus2}});
- storage.synchronize({}, {}, {}, {sourceId1, sourceId2}, {fileStatus1});
+ storage.synchronize(SynchronizationPackage{{sourceId1, sourceId2}, {fileStatus1}});
ASSERT_THAT(convert(storage.fetchAllFileStatuses()), UnorderedElementsAre(fileStatus1));
}
@@ -4206,9 +3107,9 @@ TEST_F(ProjectStorage, UpdateFileStatus)
FileStatus fileStatus1{sourceId1, 100, 100};
FileStatus fileStatus2{sourceId2, 101, 101};
FileStatus fileStatus2b{sourceId2, 102, 102};
- storage.synchronize({}, {}, {}, {sourceId1, sourceId2}, {fileStatus1, fileStatus2});
+ storage.synchronize(SynchronizationPackage{{sourceId1, sourceId2}, {fileStatus1, fileStatus2}});
- storage.synchronize({}, {}, {}, {sourceId1, sourceId2}, {fileStatus1, fileStatus2b});
+ storage.synchronize(SynchronizationPackage{{sourceId1, sourceId2}, {fileStatus1, fileStatus2b}});
ASSERT_THAT(convert(storage.fetchAllFileStatuses()),
UnorderedElementsAre(fileStatus1, fileStatus2b));
@@ -4218,7 +3119,7 @@ TEST_F(ProjectStorage, ThrowForInvalidSourceId)
{
FileStatus fileStatus1{SourceId{}, 100, 100};
- ASSERT_THROW(storage.synchronize({}, {}, {}, {sourceId1}, {fileStatus1}),
+ ASSERT_THROW(storage.synchronize(SynchronizationPackage{{sourceId1}, {fileStatus1}}),
Sqlite::ConstraintPreventsModification);
}
@@ -4226,7 +3127,7 @@ TEST_F(ProjectStorage, FetchAllFileStatuses)
{
FileStatus fileStatus1{sourceId1, 100, 100};
FileStatus fileStatus2{sourceId2, 101, 101};
- storage.synchronize({}, {}, {}, {sourceId1, sourceId2}, {fileStatus1, fileStatus2});
+ storage.synchronize(SynchronizationPackage{{sourceId1, sourceId2}, {fileStatus1, fileStatus2}});
auto fileStatuses = convert(storage.fetchAllFileStatuses());
@@ -4237,7 +3138,7 @@ TEST_F(ProjectStorage, FetchAllFileStatusesReverse)
{
FileStatus fileStatus1{sourceId1, 100, 100};
FileStatus fileStatus2{sourceId2, 101, 101};
- storage.synchronize({}, {}, {}, {sourceId1, sourceId2}, {fileStatus2, fileStatus1});
+ storage.synchronize(SynchronizationPackage{{sourceId1, sourceId2}, {fileStatus2, fileStatus1}});
auto fileStatuses = convert(storage.fetchAllFileStatuses());
@@ -4248,7 +3149,7 @@ TEST_F(ProjectStorage, FetchFileStatus)
{
FileStatus fileStatus1{sourceId1, 100, 100};
FileStatus fileStatus2{sourceId2, 101, 101};
- storage.synchronize({}, {}, {}, {sourceId1, sourceId2}, {fileStatus1, fileStatus2});
+ storage.synchronize(SynchronizationPackage{{sourceId1, sourceId2}, {fileStatus1, fileStatus2}});
auto fileStatus = storage.fetchFileStatus(sourceId1);
@@ -4257,30 +3158,18 @@ TEST_F(ProjectStorage, FetchFileStatus)
TEST_F(ProjectStorage, SynchronizeTypesWithoutTypeName)
{
- Storage::Types types{createTypesWithAliases()};
- storage.synchronize(modules,
- imports,
- types,
- {sourceId1,
- sourceId2,
- sourceId3,
- sourceId4,
- qmlModuleSourceId,
- qtQuickModuleSourceId,
- pathToModuleSourceId},
- {});
- types[3].typeName.clear();
- types[3].moduleId = ModuleId{};
- types[3].prototype = Storage::ImportedType{"Object"};
-
- storage.synchronize({}, importsSourceId4, {types[3]}, {sourceId4}, {});
+ auto package{createSynchronizationPackageWithAliases()};
+ storage.synchronize(package);
+ package.types[3].typeName.clear();
+ package.types[3].prototype = Storage::ImportedType{"Object"};
+
+ storage.synchronize(SynchronizationPackage{importsSourceId4, {package.types[3]}, {sourceId4}});
ASSERT_THAT(storage.fetchTypes(),
- Contains(AllOf(IsStorageType(pathToModuleId,
+ Contains(AllOf(IsStorageType(sourceId4,
"QObject2",
- Storage::NativeType{"QObject"},
- TypeAccessSemantics::Reference,
- sourceId4),
+ fetchTypeId(sourceId2, "QObject"),
+ TypeAccessSemantics::Reference),
Field(&Storage::Type::exportedTypes,
UnorderedElementsAre(IsExportedType("Object2"),
IsExportedType("Obj2"))))));
@@ -4288,563 +3177,481 @@ TEST_F(ProjectStorage, SynchronizeTypesWithoutTypeName)
TEST_F(ProjectStorage, FetchByMajorVersionForImportedType)
{
- auto types = createVersionedTypes();
- storage.synchronize(modules,
- imports,
- types,
- {sourceId1, qmlModuleSourceId, qtQuickModuleSourceId, pathToModuleSourceId},
- {});
- Storage::Type type{qtQuickModuleId,
- "Item",
+ auto package{createSynchronizationPackageWithVersions()};
+ storage.synchronize(package);
+ Storage::Type type{"Item",
Storage::ImportedType{"Object"},
TypeAccessSemantics::Reference,
sourceId2,
- {Storage::ExportedType{"Item", Storage::Version{}}}};
- Storage::Import import{"Qml", Storage::Version{1}, sourceId2};
+ {Storage::ExportedType{qtQuickModuleId, "Item", Storage::Version{}}}};
+ Storage::Import import{qmlModuleId, Storage::Version{1}, sourceId2};
- storage.synchronize({}, {import}, {type}, {sourceId2}, {});
+ storage.synchronize(SynchronizationPackage{{import}, {type}, {sourceId2}});
ASSERT_THAT(storage.fetchTypes(),
- Contains(IsStorageType(qtQuickModuleId,
+ Contains(IsStorageType(sourceId2,
"Item",
- Storage::NativeType{"QObject"},
- TypeAccessSemantics::Reference,
- sourceId2)));
+ fetchTypeId(sourceId1, "QObject"),
+ TypeAccessSemantics::Reference)));
}
TEST_F(ProjectStorage, FetchByMajorVersionForQualifiedImportedType)
{
- auto types = createVersionedTypes();
- storage.synchronize(modules,
- imports,
- types,
- {sourceId1, qmlModuleSourceId, qtQuickModuleSourceId, pathToModuleSourceId},
- {});
- Storage::Import import{"Qml", Storage::Version{1}, sourceId2};
- Storage::Type type{qtQuickModuleId,
- "Item",
+ auto package{createSynchronizationPackageWithVersions()};
+ storage.synchronize(package);
+ Storage::Import import{qmlModuleId, Storage::Version{1}, sourceId2};
+ Storage::Type type{"Item",
Storage::QualifiedImportedType{"Object", import},
TypeAccessSemantics::Reference,
sourceId2,
- {Storage::ExportedType{"Item", Storage::Version{}}}};
+ {Storage::ExportedType{qtQuickModuleId, "Item", Storage::Version{}}}};
- storage.synchronize({}, {import}, {type}, {sourceId2}, {});
+ storage.synchronize(SynchronizationPackage{{import}, {type}, {sourceId2}});
ASSERT_THAT(storage.fetchTypes(),
- Contains(IsStorageType(qtQuickModuleId,
+ Contains(IsStorageType(sourceId2,
"Item",
- Storage::NativeType{"QObject"},
- TypeAccessSemantics::Reference,
- sourceId2)));
+ fetchTypeId(sourceId1, "QObject"),
+ TypeAccessSemantics::Reference)));
}
TEST_F(ProjectStorage, FetchByMajorVersionAndMinorVersionForImportedType)
{
- auto types = createVersionedTypes();
- storage.synchronize(modules,
- imports,
- types,
- {sourceId1, qmlModuleSourceId, qtQuickModuleSourceId, pathToModuleSourceId},
- {});
- Storage::Type type{qtQuickModuleId,
- "Item",
+ auto package{createSynchronizationPackageWithVersions()};
+ storage.synchronize(package);
+ Storage::Type type{"Item",
Storage::ImportedType{"Obj"},
TypeAccessSemantics::Reference,
sourceId2,
- {Storage::ExportedType{"Item", Storage::Version{}}}};
- Storage::Import import{"Qml", Storage::Version{1, 2}, sourceId2};
+ {Storage::ExportedType{qtQuickModuleId, "Item", Storage::Version{}}}};
+ Storage::Import import{qmlModuleId, Storage::Version{1, 2}, sourceId2};
- storage.synchronize({}, {import}, {type}, {sourceId2}, {});
+ storage.synchronize(SynchronizationPackage{{import}, {type}, {sourceId2}});
ASSERT_THAT(storage.fetchTypes(),
- Contains(IsStorageType(qtQuickModuleId,
+ Contains(IsStorageType(sourceId2,
"Item",
- Storage::NativeType{"QObject"},
- TypeAccessSemantics::Reference,
- sourceId2)));
+ fetchTypeId(sourceId1, "QObject"),
+ TypeAccessSemantics::Reference)));
}
TEST_F(ProjectStorage, FetchByMajorVersionAndMinorVersionForQualifiedImportedType)
{
- auto types = createVersionedTypes();
- storage.synchronize(modules,
- imports,
- types,
- {sourceId1, qmlModuleSourceId, qtQuickModuleSourceId, pathToModuleSourceId},
- {});
- Storage::Import import{"Qml", Storage::Version{1, 2}, sourceId2};
- Storage::Type type{qtQuickModuleId,
- "Item",
+ auto package{createSynchronizationPackageWithVersions()};
+ storage.synchronize(package);
+ Storage::Import import{qmlModuleId, Storage::Version{1, 2}, sourceId2};
+ Storage::Type type{"Item",
Storage::QualifiedImportedType{"Obj", import},
TypeAccessSemantics::Reference,
sourceId2,
- {Storage::ExportedType{"Item", Storage::Version{}}}};
+ {Storage::ExportedType{qtQuickModuleId, "Item", Storage::Version{}}}};
- storage.synchronize({}, {import}, {type}, {sourceId2}, {});
+ storage.synchronize(SynchronizationPackage{{import}, {type}, {sourceId2}});
ASSERT_THAT(storage.fetchTypes(),
- Contains(IsStorageType(qtQuickModuleId,
+ Contains(IsStorageType(sourceId2,
"Item",
- Storage::NativeType{"QObject"},
- TypeAccessSemantics::Reference,
- sourceId2)));
+ fetchTypeId(sourceId1, "QObject"),
+ TypeAccessSemantics::Reference)));
}
TEST_F(ProjectStorage,
FetchByMajorVersionAndMinorVersionForImportedTypeIfMinorVersionIsNotExportedThrows)
{
- auto types = createVersionedTypes();
- storage.synchronize(modules,
- imports,
- types,
- {sourceId1, qmlModuleSourceId, qtQuickModuleSourceId, pathToModuleSourceId},
- {});
- Storage::Type type{qtQuickModuleId,
- "Item",
+ auto package{createSynchronizationPackageWithVersions()};
+ storage.synchronize(package);
+ Storage::Type type{"Item",
Storage::ImportedType{"Object"},
TypeAccessSemantics::Reference,
sourceId2,
- {Storage::ExportedType{"Item", Storage::Version{}}}};
- Storage::Import import{"Qml", Storage::Version{1, 1}, sourceId2};
+ {Storage::ExportedType{qtQuickModuleId, "Item", Storage::Version{}}}};
+ Storage::Import import{qmlModuleId, Storage::Version{1, 1}, sourceId2};
- ASSERT_THROW(storage.synchronize({}, {import}, {type}, {sourceId2}, {}),
+ ASSERT_THROW(storage.synchronize(SynchronizationPackage{{import}, {type}, {sourceId2}}),
QmlDesigner::TypeNameDoesNotExists);
}
TEST_F(ProjectStorage,
FetchByMajorVersionAndMinorVersionForQualifiedImportedTypeIfMinorVersionIsNotExportedThrows)
{
- auto types = createVersionedTypes();
- storage.synchronize(modules,
- imports,
- types,
- {sourceId1, qmlModuleSourceId, qtQuickModuleSourceId, pathToModuleSourceId},
- {});
- Storage::Import import{"Qml", Storage::Version{1, 1}, sourceId2};
- Storage::Type type{qtQuickModuleId,
- "Item",
+ auto package{createSynchronizationPackageWithVersions()};
+ storage.synchronize(package);
+ Storage::Import import{qmlModuleId, Storage::Version{1, 1}, sourceId2};
+ Storage::Type type{"Item",
Storage::QualifiedImportedType{"Object", import},
TypeAccessSemantics::Reference,
sourceId2,
- {Storage::ExportedType{"Item", Storage::Version{}}}};
+ {Storage::ExportedType{qtQuickModuleId, "Item", Storage::Version{}}}};
- ASSERT_THROW(storage.synchronize({}, {import}, {type}, {sourceId2}, {}),
+ ASSERT_THROW(storage.synchronize(SynchronizationPackage{{import}, {type}, {sourceId2}}),
QmlDesigner::TypeNameDoesNotExists);
}
TEST_F(ProjectStorage, FetchLowMinorVersionForImportedTypeThrows)
{
- auto types = createVersionedTypes();
- storage.synchronize(modules,
- imports,
- types,
- {sourceId1, qmlModuleSourceId, qtQuickModuleSourceId, pathToModuleSourceId},
- {});
- Storage::Type type{qtQuickModuleId,
- "Item",
+ auto package{createSynchronizationPackageWithVersions()};
+ storage.synchronize(package);
+ Storage::Type type{"Item",
Storage::ImportedType{"Obj"},
TypeAccessSemantics::Reference,
sourceId2,
- {Storage::ExportedType{"Item", Storage::Version{}}}};
- Storage::Import import{"Qml", Storage::Version{1, 1}, sourceId2};
+ {Storage::ExportedType{qtQuickModuleId, "Item", Storage::Version{}}}};
+ Storage::Import import{qmlModuleId, Storage::Version{1, 1}, sourceId2};
- ASSERT_THROW(storage.synchronize({}, {import}, {type}, {sourceId2}, {}),
+ ASSERT_THROW(storage.synchronize(SynchronizationPackage{{import}, {type}, {sourceId2}}),
QmlDesigner::TypeNameDoesNotExists);
}
TEST_F(ProjectStorage, FetchLowMinorVersionForQualifiedImportedTypeThrows)
{
- auto types = createVersionedTypes();
- storage.synchronize(modules,
- imports,
- types,
- {sourceId1, qmlModuleSourceId, qtQuickModuleSourceId, pathToModuleSourceId},
- {});
- Storage::Import import{"Qml", Storage::Version{1, 1}, sourceId2};
- Storage::Type type{qtQuickModuleId,
- "Item",
+ auto package{createSynchronizationPackageWithVersions()};
+ storage.synchronize(package);
+ Storage::Import import{qmlModuleId, Storage::Version{1, 1}, sourceId2};
+ Storage::Type type{"Item",
Storage::QualifiedImportedType{"Obj", import},
TypeAccessSemantics::Reference,
sourceId2,
- {Storage::ExportedType{"Item", Storage::Version{}}}};
+ {Storage::ExportedType{qtQuickModuleId, "Item", Storage::Version{}}}};
- ASSERT_THROW(storage.synchronize({}, {import}, {type}, {sourceId2}, {}),
+ ASSERT_THROW(storage.synchronize(SynchronizationPackage{{import}, {type}, {sourceId2}}),
QmlDesigner::TypeNameDoesNotExists);
}
TEST_F(ProjectStorage, FetchHigherMinorVersionForImportedType)
{
- auto types = createVersionedTypes();
- storage.synchronize(modules,
- imports,
- types,
- {sourceId1, qmlModuleSourceId, qtQuickModuleSourceId, pathToModuleSourceId},
- {});
- Storage::Type type{qtQuickModuleId,
- "Item",
+ auto package{createSynchronizationPackageWithVersions()};
+ storage.synchronize(package);
+ Storage::Type type{"Item",
Storage::ImportedType{"Obj"},
TypeAccessSemantics::Reference,
sourceId2,
- {Storage::ExportedType{"Item", Storage::Version{}}}};
- Storage::Import import{"Qml", Storage::Version{1, 3}, sourceId2};
+ {Storage::ExportedType{qtQuickModuleId, "Item", Storage::Version{}}}};
+ Storage::Import import{qmlModuleId, Storage::Version{1, 3}, sourceId2};
- storage.synchronize({}, {import}, {type}, {sourceId2}, {});
+ storage.synchronize(SynchronizationPackage{{import}, {type}, {sourceId2}});
ASSERT_THAT(storage.fetchTypes(),
- Contains(IsStorageType(qtQuickModuleId,
+ Contains(IsStorageType(sourceId2,
"Item",
- Storage::NativeType{"QObject"},
- TypeAccessSemantics::Reference,
- sourceId2)));
+ fetchTypeId(sourceId1, "QObject"),
+ TypeAccessSemantics::Reference)));
}
TEST_F(ProjectStorage, FetchHigherMinorVersionForQualifiedImportedType)
{
- auto types = createVersionedTypes();
- storage.synchronize(modules,
- imports,
- types,
- {sourceId1, qmlModuleSourceId, qtQuickModuleSourceId, pathToModuleSourceId},
- {});
- Storage::Import import{"Qml", Storage::Version{1, 3}, sourceId2};
- Storage::Type type{qtQuickModuleId,
- "Item",
+ auto package{createSynchronizationPackageWithVersions()};
+ storage.synchronize(package);
+ Storage::Import import{qmlModuleId, Storage::Version{1, 3}, sourceId2};
+ Storage::Type type{"Item",
Storage::QualifiedImportedType{"Obj", import},
TypeAccessSemantics::Reference,
sourceId2,
- {Storage::ExportedType{"Item", Storage::Version{}}}};
+ {Storage::ExportedType{qtQuickModuleId, "Item", Storage::Version{}}}};
- storage.synchronize({}, {import}, {type}, {sourceId2}, {});
+ storage.synchronize(SynchronizationPackage{{import}, {type}, {sourceId2}});
ASSERT_THAT(storage.fetchTypes(),
- Contains(IsStorageType(qtQuickModuleId,
+ Contains(IsStorageType(sourceId2,
"Item",
- Storage::NativeType{"QObject"},
- TypeAccessSemantics::Reference,
- sourceId2)));
+ fetchTypeId(sourceId1, "QObject"),
+ TypeAccessSemantics::Reference)));
}
TEST_F(ProjectStorage, FetchDifferentMajorVersionForImportedTypeThrows)
{
- auto types = createVersionedTypes();
- storage.synchronize(modules,
- imports,
- types,
- {sourceId1, qmlModuleSourceId, qtQuickModuleSourceId, pathToModuleSourceId},
- {});
- Storage::Type type{qtQuickModuleId,
- "Item",
+ auto package{createSynchronizationPackageWithVersions()};
+ storage.synchronize(package);
+ Storage::Type type{"Item",
Storage::ImportedType{"Obj"},
TypeAccessSemantics::Reference,
sourceId2,
- {Storage::ExportedType{"Item", Storage::Version{}}}};
- Storage::Import import{"Qml", Storage::Version{3, 1}, sourceId2};
+ {Storage::ExportedType{qtQuickModuleId, "Item", Storage::Version{}}}};
+ Storage::Import import{qmlModuleId, Storage::Version{3, 1}, sourceId2};
- ASSERT_THROW(storage.synchronize({}, {import}, {type}, {sourceId2}, {}),
+ ASSERT_THROW(storage.synchronize(SynchronizationPackage{{import}, {type}, {sourceId2}}),
QmlDesigner::TypeNameDoesNotExists);
}
TEST_F(ProjectStorage, FetchDifferentMajorVersionForQualifiedImportedTypeThrows)
{
- auto types = createVersionedTypes();
- storage.synchronize(modules,
- imports,
- types,
- {sourceId1, qmlModuleSourceId, qtQuickModuleSourceId, pathToModuleSourceId},
- {});
- Storage::Import import{"Qml", Storage::Version{3, 1}, sourceId2};
- Storage::Type type{qtQuickModuleId,
- "Item",
+ auto package{createSynchronizationPackageWithVersions()};
+ storage.synchronize(package);
+ Storage::Import import{qmlModuleId, Storage::Version{3, 1}, sourceId2};
+ Storage::Type type{"Item",
Storage::QualifiedImportedType{"Obj", import},
TypeAccessSemantics::Reference,
sourceId2,
- {Storage::ExportedType{"Item", Storage::Version{}}}};
+ {Storage::ExportedType{qtQuickModuleId, "Item", Storage::Version{}}}};
- ASSERT_THROW(storage.synchronize({}, {import}, {type}, {sourceId2}, {}),
+ ASSERT_THROW(storage.synchronize(SynchronizationPackage{{import}, {type}, {sourceId2}}),
QmlDesigner::TypeNameDoesNotExists);
}
TEST_F(ProjectStorage, FetchOtherTypeByDifferentVersionForImportedType)
{
- auto types = createVersionedTypes();
- storage.synchronize(modules,
- imports,
- types,
- {sourceId1, qmlModuleSourceId, qtQuickModuleSourceId, pathToModuleSourceId},
- {});
- Storage::Type type{qtQuickModuleId,
- "Item",
+ auto package{createSynchronizationPackageWithVersions()};
+ storage.synchronize(package);
+ Storage::Type type{"Item",
Storage::ImportedType{"Obj"},
TypeAccessSemantics::Reference,
sourceId2,
- {Storage::ExportedType{"Item", Storage::Version{}}}};
- Storage::Import import{"Qml", Storage::Version{2, 3}, sourceId2};
+ {Storage::ExportedType{qtQuickModuleId, "Item", Storage::Version{}}}};
+ Storage::Import import{qmlModuleId, Storage::Version{2, 3}, sourceId2};
- storage.synchronize({}, {import}, {type}, {sourceId2}, {});
+ storage.synchronize(SynchronizationPackage{{import}, {type}, {sourceId2}});
ASSERT_THAT(storage.fetchTypes(),
- Contains(IsStorageType(qtQuickModuleId,
+ Contains(IsStorageType(sourceId2,
"Item",
- Storage::NativeType{"QObject2"},
- TypeAccessSemantics::Reference,
- sourceId2)));
+ fetchTypeId(sourceId1, "QObject2"),
+ TypeAccessSemantics::Reference)));
}
TEST_F(ProjectStorage, FetchOtherTypeByDifferentVersionForQualifiedImportedType)
{
- auto types = createVersionedTypes();
- storage.synchronize(modules,
- imports,
- types,
- {sourceId1, qmlModuleSourceId, qtQuickModuleSourceId, pathToModuleSourceId},
- {});
- Storage::Import import{"Qml", Storage::Version{2, 3}, sourceId2};
- Storage::Type type{qtQuickModuleId,
- "Item",
+ auto package{createSynchronizationPackageWithVersions()};
+ storage.synchronize(package);
+ Storage::Import import{qmlModuleId, Storage::Version{2, 3}, sourceId2};
+ Storage::Type type{"Item",
Storage::QualifiedImportedType{"Obj", import},
TypeAccessSemantics::Reference,
sourceId2,
- {Storage::ExportedType{"Item", Storage::Version{}}}};
+ {Storage::ExportedType{qtQuickModuleId, "Item", Storage::Version{}}}};
- storage.synchronize({}, {import}, {type}, {sourceId2}, {});
+ storage.synchronize(SynchronizationPackage{{import}, {type}, {sourceId2}});
ASSERT_THAT(storage.fetchTypes(),
- Contains(IsStorageType(qtQuickModuleId,
+ Contains(IsStorageType(sourceId2,
"Item",
- Storage::NativeType{"QObject2"},
- TypeAccessSemantics::Reference,
- sourceId2)));
+ fetchTypeId(sourceId1, "QObject2"),
+ TypeAccessSemantics::Reference)));
}
TEST_F(ProjectStorage, FetchHighestVersionForImportWithoutVersionForImportedType)
{
- auto types = createVersionedTypes();
- storage.synchronize(modules,
- imports,
- types,
- {sourceId1, qmlModuleSourceId, qtQuickModuleSourceId, pathToModuleSourceId},
- {});
- Storage::Type type{qtQuickModuleId,
- "Item",
+ auto package{createSynchronizationPackageWithVersions()};
+ storage.synchronize(package);
+ Storage::Type type{"Item",
Storage::ImportedType{"Obj"},
TypeAccessSemantics::Reference,
sourceId2,
- {Storage::ExportedType{"Item", Storage::Version{}}}};
- Storage::Import import{"Qml", Storage::Version{}, sourceId2};
+ {Storage::ExportedType{qtQuickModuleId, "Item", Storage::Version{}}}};
+ Storage::Import import{qmlModuleId, Storage::Version{}, sourceId2};
- storage.synchronize({}, {import}, {type}, {sourceId2}, {});
+ storage.synchronize(SynchronizationPackage{{import}, {type}, {sourceId2}});
ASSERT_THAT(storage.fetchTypes(),
- Contains(IsStorageType(qtQuickModuleId,
+ Contains(IsStorageType(sourceId2,
"Item",
- Storage::NativeType{"QObject4"},
- TypeAccessSemantics::Reference,
- sourceId2)));
+ fetchTypeId(sourceId1, "QObject4"),
+ TypeAccessSemantics::Reference)));
}
TEST_F(ProjectStorage, FetchHighestVersionForImportWithoutVersionForQualifiedImportedType)
{
- auto types = createVersionedTypes();
- storage.synchronize(modules,
- imports,
- types,
- {sourceId1, qmlModuleSourceId, qtQuickModuleSourceId, pathToModuleSourceId},
- {});
- Storage::Import import{"Qml", Storage::Version{}, sourceId2};
- Storage::Type type{qtQuickModuleId,
- "Item",
+ auto package{createSynchronizationPackageWithVersions()};
+ storage.synchronize(package);
+ Storage::Import import{qmlModuleId, Storage::Version{}, sourceId2};
+ Storage::Type type{"Item",
Storage::QualifiedImportedType{"Obj", import},
TypeAccessSemantics::Reference,
sourceId2,
- {Storage::ExportedType{"Item", Storage::Version{}}}};
+ {Storage::ExportedType{qtQuickModuleId, "Item", Storage::Version{}}}};
- storage.synchronize({}, {import}, {type}, {sourceId2}, {});
+ storage.synchronize(SynchronizationPackage{{import}, {type}, {sourceId2}});
ASSERT_THAT(storage.fetchTypes(),
- Contains(IsStorageType(qtQuickModuleId,
+ Contains(IsStorageType(sourceId2,
"Item",
- Storage::NativeType{"QObject4"},
- TypeAccessSemantics::Reference,
- sourceId2)));
+ fetchTypeId(sourceId1, "QObject4"),
+ TypeAccessSemantics::Reference)));
}
TEST_F(ProjectStorage, FetchHighestVersionForImportWithMajorVersionForImportedType)
{
- auto types = createVersionedTypes();
- storage.synchronize(modules,
- imports,
- types,
- {sourceId1, qmlModuleSourceId, qtQuickModuleSourceId, pathToModuleSourceId},
- {});
- Storage::Type type{qtQuickModuleId,
- "Item",
+ auto package{createSynchronizationPackageWithVersions()};
+ storage.synchronize(package);
+ Storage::Type type{"Item",
Storage::ImportedType{"Obj"},
TypeAccessSemantics::Reference,
sourceId2,
- {Storage::ExportedType{"Item", Storage::Version{}}}};
- Storage::Import import{"Qml", Storage::Version{2}, sourceId2};
+ {Storage::ExportedType{qtQuickModuleId, "Item", Storage::Version{}}}};
+ Storage::Import import{qmlModuleId, Storage::Version{2}, sourceId2};
- storage.synchronize({}, {import}, {type}, {sourceId2}, {});
+ storage.synchronize(SynchronizationPackage{{import}, {type}, {sourceId2}});
ASSERT_THAT(storage.fetchTypes(),
- Contains(IsStorageType(qtQuickModuleId,
+ Contains(IsStorageType(sourceId2,
"Item",
- Storage::NativeType{"QObject3"},
- TypeAccessSemantics::Reference,
- sourceId2)));
+ fetchTypeId(sourceId1, "QObject3"),
+ TypeAccessSemantics::Reference)));
}
TEST_F(ProjectStorage, FetchHighestVersionForImportWithMajorVersionForQualifiedImportedType)
{
- auto types = createVersionedTypes();
- storage.synchronize(modules,
- imports,
- types,
- {sourceId1, qmlModuleSourceId, qtQuickModuleSourceId, pathToModuleSourceId},
- {});
- Storage::Import import{"Qml", Storage::Version{2}, sourceId2};
- Storage::Type type{qtQuickModuleId,
- "Item",
+ auto package{createSynchronizationPackageWithVersions()};
+ storage.synchronize(package);
+ Storage::Import import{qmlModuleId, Storage::Version{2}, sourceId2};
+ Storage::Type type{"Item",
Storage::QualifiedImportedType{"Obj", import},
TypeAccessSemantics::Reference,
sourceId2,
- {Storage::ExportedType{"Item", Storage::Version{}}}};
+ {Storage::ExportedType{qtQuickModuleId, "Item", Storage::Version{}}}};
- storage.synchronize({}, {import}, {type}, {sourceId2}, {});
+ storage.synchronize(SynchronizationPackage{{import}, {type}, {sourceId2}});
ASSERT_THAT(storage.fetchTypes(),
- Contains(IsStorageType(qtQuickModuleId,
+ Contains(IsStorageType(sourceId2,
"Item",
- Storage::NativeType{"QObject3"},
- TypeAccessSemantics::Reference,
- sourceId2)));
+ fetchTypeId(sourceId1, "QObject3"),
+ TypeAccessSemantics::Reference)));
}
TEST_F(ProjectStorage, FetchExportedTypeWithoutVersionFirstForImportedType)
{
- auto types = createVersionedTypes();
- storage.synchronize(modules,
- imports,
- types,
- {sourceId1, qmlModuleSourceId, qtQuickModuleSourceId, pathToModuleSourceId},
- {});
- Storage::Type type{qtQuickModuleId,
- "Item",
+ auto package{createSynchronizationPackageWithVersions()};
+ storage.synchronize(package);
+ Storage::Type type{"Item",
Storage::ImportedType{"BuiltInObj"},
TypeAccessSemantics::Reference,
sourceId2,
- {Storage::ExportedType{"Item", Storage::Version{}}}};
- Storage::Import import{"Qml", Storage::Version{}, sourceId2};
+ {Storage::ExportedType{qtQuickModuleId, "Item", Storage::Version{}}}};
+ Storage::Import import{qmlModuleId, Storage::Version{}, sourceId2};
- storage.synchronize({}, {import}, {type}, {sourceId2}, {});
+ storage.synchronize(SynchronizationPackage{{import}, {type}, {sourceId2}});
ASSERT_THAT(storage.fetchTypes(),
- Contains(IsStorageType(qtQuickModuleId,
+ Contains(IsStorageType(sourceId2,
"Item",
- Storage::NativeType{"QObject"},
- TypeAccessSemantics::Reference,
- sourceId2)));
+ fetchTypeId(sourceId1, "QObject"),
+ TypeAccessSemantics::Reference)));
}
TEST_F(ProjectStorage, FetchExportedTypeWithoutVersionFirstForQualifiedImportedType)
{
- auto types = createVersionedTypes();
- storage.synchronize(modules,
- imports,
- types,
- {sourceId1, qmlModuleSourceId, qtQuickModuleSourceId, pathToModuleSourceId},
- {});
- Storage::Import import{"Qml", Storage::Version{}, sourceId2};
- Storage::Type type{qtQuickModuleId,
- "Item",
+ auto package{createSynchronizationPackageWithVersions()};
+ storage.synchronize(package);
+ Storage::Import import{qmlModuleId, Storage::Version{}, sourceId2};
+ Storage::Type type{"Item",
Storage::QualifiedImportedType{"BuiltInObj", import},
TypeAccessSemantics::Reference,
sourceId2,
- {Storage::ExportedType{"Item", Storage::Version{}}}};
+ {Storage::ExportedType{qtQuickModuleId, "Item", Storage::Version{}}}};
- storage.synchronize({}, {import}, {type}, {sourceId2}, {});
+ storage.synchronize(SynchronizationPackage{{import}, {type}, {sourceId2}});
ASSERT_THAT(storage.fetchTypes(),
- Contains(IsStorageType(qtQuickModuleId,
+ Contains(IsStorageType(sourceId2,
"Item",
- Storage::NativeType{"QObject"},
- TypeAccessSemantics::Reference,
- sourceId2)));
+ fetchTypeId(sourceId1, "QObject"),
+ TypeAccessSemantics::Reference)));
}
TEST_F(ProjectStorage, EnsureThatPropertiesForRemovedTypesAreNotAnymoreRelinked)
{
- Storage::Type type{qmlModuleId,
- "QObject",
- Storage::NativeType{""},
+ Storage::Type type{"QObject",
+ Storage::ImportedType{""},
TypeAccessSemantics::Reference,
sourceId1,
- {Storage::ExportedType{"Object", Storage::Version{}}},
+ {Storage::ExportedType{qmlModuleId, "Object", Storage::Version{}}},
{Storage::PropertyDeclaration{"data",
- Storage::NativeType{"QObject"},
+ Storage::ImportedType{"Object"},
Storage::PropertyDeclarationTraits::IsList}}};
- Storage::Import import{"Qml", Storage::Version{}, sourceId1};
- storage.synchronize(modules,
- {import},
- {type},
- {sourceId1, qmlModuleSourceId, qtQuickModuleSourceId, pathToModuleSourceId},
- {});
+ Storage::Import import{qmlModuleId, Storage::Version{}, sourceId1};
+ storage.synchronize(SynchronizationPackage{{import}, {type}, {sourceId1}});
- ASSERT_NO_THROW(storage.synchronize({}, {}, {}, {sourceId1}, {}));
+ ASSERT_NO_THROW(storage.synchronize(SynchronizationPackage{{sourceId1}}));
}
TEST_F(ProjectStorage, EnsureThatPrototypesForRemovedTypesAreNotAnymoreRelinked)
{
- auto types = createTypes();
- storage.synchronize(
- modules,
- imports,
- types,
- {sourceId1, sourceId2, qmlModuleSourceId, qtQuickModuleSourceId, pathToModuleSourceId},
- {});
+ auto package{createSimpleSynchronizationPackage()};
+ storage.synchronize(package);
- ASSERT_NO_THROW(storage.synchronize({}, {}, {}, {sourceId1, sourceId2}, {}));
+ ASSERT_NO_THROW(storage.synchronize(SynchronizationPackage{{sourceId1, sourceId2}}));
}
TEST_F(ProjectStorage, MinimalUpdates)
{
- auto types = createTypes();
- storage.synchronize(
- modules,
- imports,
- types,
- {sourceId1, sourceId2, qmlModuleSourceId, qtQuickModuleSourceId, pathToModuleSourceId},
- {});
- Storage::Type quickType{qtQuickModuleId,
- "QQuickItem",
+ auto package{createSimpleSynchronizationPackage()};
+ storage.synchronize(package);
+ Storage::Type quickType{"QQuickItem",
{},
TypeAccessSemantics::Reference,
sourceId1,
- {Storage::ExportedType{"Item", Storage::Version{2, 0}}},
+ {Storage::ExportedType{qtQuickModuleId, "Item", Storage::Version{2, 0}},
+ Storage::ExportedType{qtQuickNativeModuleId, "QQuickItem"}},
{},
{},
{},
{},
Storage::ChangeLevel::Minimal};
- storage.synchronize({modules[1]}, {}, {quickType}, {qtQuickModuleSourceId}, {});
+ storage.synchronize(SynchronizationPackage{{quickType}});
- ASSERT_THAT(storage.fetchTypes(),
- UnorderedElementsAre(AllOf(IsStorageType(qmlModuleId,
- "QObject",
- Storage::NativeType{},
- TypeAccessSemantics::Reference,
- sourceId2),
- Field(&Storage::Type::exportedTypes,
- UnorderedElementsAre(IsExportedType("Object"),
- IsExportedType("Obj")))),
- AllOf(IsStorageType(qtQuickModuleId,
- "QQuickItem",
- Storage::NativeType{"QObject"},
- TypeAccessSemantics::Reference,
- sourceId1),
- Field(&Storage::Type::exportedTypes,
- UnorderedElementsAre(IsExportedType("Item", 2, 0))))));
+ ASSERT_THAT(
+ storage.fetchTypes(),
+ UnorderedElementsAre(
+ AllOf(IsStorageType(sourceId2, "QObject", TypeId{}, TypeAccessSemantics::Reference),
+ Field(&Storage::Type::exportedTypes,
+ UnorderedElementsAre(IsExportedType(qmlModuleId, "Object"),
+ IsExportedType(qmlModuleId, "Obj"),
+ IsExportedType(qmlNativeModuleId, "QObject")))),
+ AllOf(IsStorageType(sourceId1,
+ "QQuickItem",
+ fetchTypeId(sourceId2, "QObject"),
+ TypeAccessSemantics::Reference),
+ Field(&Storage::Type::exportedTypes,
+ UnorderedElementsAre(IsExportedType(qtQuickModuleId, "Item", 2, 0),
+ IsExportedType(qtQuickNativeModuleId, "QQuickItem"))),
+ Field(&Storage::Type::propertyDeclarations, Not(IsEmpty())),
+ Field(&Storage::Type::functionDeclarations, Not(IsEmpty())),
+ Field(&Storage::Type::signalDeclarations, Not(IsEmpty())),
+ Field(&Storage::Type::enumerationDeclarations, Not(IsEmpty())))));
+}
+
+TEST_F(ProjectStorage, GetModuleId)
+{
+ auto id = storage.moduleId("Qml");
+
+ ASSERT_TRUE(id);
+}
+
+TEST_F(ProjectStorage, GetSameModuleIdAgain)
+{
+ auto initialId = storage.moduleId("Qml");
+
+ auto id = storage.moduleId("Qml");
+
+ ASSERT_THAT(id, Eq(initialId));
+}
+
+TEST_F(ProjectStorage, ModuleNameThrowsIfIdIsInvalid)
+{
+ ASSERT_THROW(storage.moduleName(ModuleId{}), QmlDesigner::ModuleDoesNotExists);
+}
+
+TEST_F(ProjectStorage, ModuleNameThrowsIfIdDoesNotExists)
+{
+ ASSERT_THROW(storage.moduleName(ModuleId{222}), QmlDesigner::ModuleDoesNotExists);
+}
+
+TEST_F(ProjectStorage, GetModuleName)
+{
+ auto id = storage.moduleId("Qml");
+
+ auto name = storage.moduleName(id);
+
+ ASSERT_THAT(name, Eq("Qml"));
+}
+
+TEST_F(ProjectStorage, PopulateModuleCache)
+{
+ auto id = storage.moduleId("Qml");
+
+ QmlDesigner::ProjectStorage<Sqlite::Database> newStorage{database, database.isInitialized()};
+
+ ASSERT_THAT(newStorage.moduleName(id), Eq("Qml"));
}
} // namespace
diff --git a/tests/unit/unittest/projectstoragemock.h b/tests/unit/unittest/projectstoragemock.h
index 6fecc58ad4..42de0b0b40 100644
--- a/tests/unit/unittest/projectstoragemock.h
+++ b/tests/unit/unittest/projectstoragemock.h
@@ -36,22 +36,17 @@
class ProjectStorageMock : public QmlDesigner::ProjectStorageInterface
{
public:
- MOCK_METHOD(void,
- synchronize,
- (QmlDesigner::Storage::Modules modules,
- QmlDesigner::Storage::Imports imports,
- QmlDesigner::Storage::Types types,
- QmlDesigner::SourceIds sourceIds,
- QmlDesigner::FileStatuses fileStatuses),
- (override));
+ MOCK_METHOD(void, synchronize, (QmlDesigner::Storage::SynchronizationPackage package), (override));
+
+ MOCK_METHOD(QmlDesigner::ModuleId, moduleId, (Utils::SmallStringView), (override));
MOCK_METHOD(QmlDesigner::FileStatus,
fetchFileStatus,
(QmlDesigner::SourceId sourceId),
(const, override));
- MOCK_METHOD(QmlDesigner::SourceIds,
- fetchSourceDependencieIds,
+ MOCK_METHOD(QmlDesigner::Storage::ProjectDatas,
+ fetchProjectDatas,
(QmlDesigner::SourceId sourceId),
(const, override));
diff --git a/tests/unit/unittest/projectstorageupdater-test.cpp b/tests/unit/unittest/projectstorageupdater-test.cpp
index d198587821..c26aaa7b70 100644
--- a/tests/unit/unittest/projectstorageupdater-test.cpp
+++ b/tests/unit/unittest/projectstorageupdater-test.cpp
@@ -42,26 +42,26 @@ namespace {
namespace Storage = QmlDesigner::Storage;
using QmlDesigner::FileStatus;
+using QmlDesigner::ModuleId;
using QmlDesigner::SourceId;
using QmlDesigner::Storage::TypeAccessSemantics;
namespace Storage = QmlDesigner::Storage;
using QmlDesigner::IdPaths;
+using QmlDesigner::Storage::SynchronizationPackage;
using QmlDesigner::Storage::Version;
-MATCHER_P5(IsStorageType,
- moduleId,
+MATCHER_P4(IsStorageType,
typeName,
prototype,
accessSemantics,
sourceId,
std::string(negation ? "isn't " : "is ")
- + PrintToString(Storage::Type{moduleId, typeName, prototype, accessSemantics, sourceId}))
+ + PrintToString(Storage::Type{typeName, prototype, accessSemantics, sourceId}))
{
const Storage::Type &type = arg;
- return type.moduleId == moduleId && type.typeName == typeName
- && type.accessSemantics == accessSemantics && type.sourceId == sourceId
- && Storage::ImportedTypeName{prototype} == type.prototype;
+ return type.typeName == typeName && type.accessSemantics == accessSemantics
+ && type.sourceId == sourceId && Storage::ImportedTypeName{prototype} == type.prototype;
}
MATCHER_P3(IsPropertyDeclaration,
@@ -78,27 +78,20 @@ MATCHER_P3(IsPropertyDeclaration,
&& propertyDeclaration.traits == traits;
}
-MATCHER_P3(IsExportedType,
+MATCHER_P4(IsExportedType,
+ moduleId,
name,
majorVersion,
minorVersion,
std::string(negation ? "isn't " : "is ")
- + PrintToString(Storage::ExportedType{name,
+ + PrintToString(Storage::ExportedType{moduleId,
+ name,
Storage::Version{majorVersion, minorVersion}}))
{
const Storage::ExportedType &type = arg;
- return type.name == name && type.version == Storage::Version{majorVersion, minorVersion};
-}
-
-MATCHER_P2(IsModule,
- name,
- sourceId,
- std::string(negation ? "isn't " : "is ") + PrintToString(Storage::Module{name, sourceId}))
-{
- const Storage::Module &module = arg;
-
- return module.name == name && module.sourceId == sourceId;
+ return type.moduleId == moduleId && type.name == name
+ && type.version == Storage::Version{majorVersion, minorVersion};
}
MATCHER_P3(IsFileStatus,
@@ -114,6 +107,14 @@ MATCHER_P3(IsFileStatus,
&& fileStatus.lastModified == lastModified;
}
+MATCHER(PackageIsEmpty, std::string(negation ? "isn't empty" : "is empty"))
+{
+ const Storage::SynchronizationPackage &package = arg;
+
+ return package.imports.empty() && package.types.empty() && package.fileStatuses.empty()
+ && package.sourceIds.empty();
+}
+
class ProjectStorageUpdater : public testing::Test
{
public:
@@ -134,8 +135,10 @@ public:
ON_CALL(projectStorageMock, fetchFileStatus(Eq(qmlDirPathSourceId)))
.WillByDefault(Return(FileStatus{qmlDirPathSourceId, 2, 421}));
- ON_CALL(projectStorageMock, fetchSourceDependencieIds(Eq(qmlDirPathSourceId)))
- .WillByDefault(Return(QmlDesigner::SourceIds{qmltypesPathSourceId, qmltypes2PathSourceId}));
+ ON_CALL(projectStorageMock, fetchProjectDatas(Eq(qmlDirPathSourceId)))
+ .WillByDefault(
+ Return(QmlDesigner::Storage::ProjectDatas{{ModuleId{}, qmltypesPathSourceId},
+ {ModuleId{}, qmltypes2PathSourceId}}));
QString qmldir{"module Example\ntypeinfo example.qmltypes\n"};
ON_CALL(projectManagerMock, qtQmlDirs()).WillByDefault(Return(QStringList{"/path/qmldir"}));
@@ -154,6 +157,8 @@ public:
.WillByDefault(Return(FileStatus{qmlDocumentSourceId3, 22, 14}));
ON_CALL(projectStorageMock, fetchFileStatus(Eq(qmlDocumentSourceId3)))
.WillByDefault(Return(FileStatus{qmlDocumentSourceId3, 22, 2}));
+ ON_CALL(projectStorageMock, moduleId(Eq("Example"))).WillByDefault(Return(exampleModuleId));
+ ON_CALL(projectStorageMock, moduleId(Eq("Qml"))).WillByDefault(Return(qmlModuleId));
firstType.prototype = Storage::ImportedType{"Object"};
secondType.prototype = Storage::ImportedType{"Object2"};
@@ -203,25 +208,26 @@ protected:
SourceId qmltypesPathSourceId = sourcePathCache.sourceId("/path/example.qmltypes");
SourceId qmltypes2PathSourceId = sourcePathCache.sourceId("/path/example2.qmltypes");
SourceId qmlDirPathSourceId = sourcePathCache.sourceId("/path/qmldir");
- QmlDesigner::ModuleId exampleModuleId{&qmlDirPathSourceId};
SourceId qmlDocumentSourceId1 = sourcePathCache.sourceId("/path/First.qml");
SourceId qmlDocumentSourceId2 = sourcePathCache.sourceId("/path/First.2.qml");
SourceId qmlDocumentSourceId3 = sourcePathCache.sourceId("/path/Second.qml");
- Storage::Type objectType{exampleModuleId,
- "QObject",
+ ModuleId qmlModuleId{storage.moduleId("Qml")};
+ ModuleId exampleModuleId{storage.moduleId("Example")};
+ Storage::Type objectType{"QObject",
Storage::NativeType{},
Storage::TypeAccessSemantics::Reference,
objectTypeSourceId,
- {Storage::ExportedType{"Object"}, Storage::ExportedType{"Obj"}}};
+ {Storage::ExportedType{exampleModuleId, "Object"},
+ Storage::ExportedType{exampleModuleId, "Obj"}}};
QString qmlDocument1{"First{}"};
QString qmlDocument2{"Second{}"};
QString qmlDocument3{"Third{}"};
Storage::Type firstType;
Storage::Type secondType;
Storage::Type thirdType;
- Storage::Import import1{"Qml", Storage::Version{2, 3}, qmlDocumentSourceId1};
- Storage::Import import2{"Qml", Storage::Version{}, qmlDocumentSourceId2};
- Storage::Import import3{"Qml", Storage::Version{2}, qmlDocumentSourceId3};
+ Storage::Import import1{qmlModuleId, Storage::Version{2, 3}, qmlDocumentSourceId1};
+ Storage::Import import2{qmlModuleId, Storage::Version{}, qmlDocumentSourceId2};
+ Storage::Import import3{qmlModuleId, Storage::Version{2}, qmlDocumentSourceId3};
};
TEST_F(ProjectStorageUpdater, GetContentForQmlDirPathsIfFileStatusIsDifferent)
@@ -320,8 +326,7 @@ TEST_F(ProjectStorageUpdater, SynchronizeIsEmptyForNoChange)
ON_CALL(projectStorageMock, fetchFileStatus(Eq(qmlDirPathSourceId)))
.WillByDefault(Return(FileStatus{qmlDirPathSourceId, 21, 421}));
- EXPECT_CALL(projectStorageMock,
- synchronize(IsEmpty(), IsEmpty(), IsEmpty(), IsEmpty(), IsEmpty()));
+ EXPECT_CALL(projectStorageMock, synchronize(PackageIsEmpty()));
updater.update();
}
@@ -330,23 +335,26 @@ TEST_F(ProjectStorageUpdater, SynchronizeQmlTypes)
{
auto qmlDirPathSourceId = sourcePathCache.sourceId("/path/qmldir");
auto qmltypesPathSourceId = sourcePathCache.sourceId("/path/example.qmltypes");
- Storage::Import import{"Qml", Storage::Version{2, 3}, qmltypesPathSourceId};
+ Storage::Import import{qmlModuleId, Storage::Version{2, 3}, qmltypesPathSourceId};
QString qmltypes{"Module {\ndependencies: []}"};
ON_CALL(fileSystemMock, contentAsQString(Eq(QString("/path/example.qmltypes"))))
.WillByDefault(Return(qmltypes));
ON_CALL(qmlTypesParserMock, parse(qmltypes, _, _, _))
- .WillByDefault([&](auto, auto &imports, auto &types, auto &sourceIds) {
+ .WillByDefault([&](auto, auto &imports, auto &types, auto) {
types.push_back(objectType);
imports.push_back(import);
});
+ EXPECT_CALL(projectStorageMock, moduleId(Eq("Example")));
EXPECT_CALL(projectStorageMock,
- synchronize(ElementsAre(IsModule("Example", qmlDirPathSourceId)),
- ElementsAre(import),
- ElementsAre(Eq(objectType)),
- UnorderedElementsAre(qmlDirPathSourceId, qmltypesPathSourceId),
- UnorderedElementsAre(IsFileStatus(qmlDirPathSourceId, 21, 421),
- IsFileStatus(qmltypesPathSourceId, 21, 421))));
+ synchronize(
+ AllOf(Field(&SynchronizationPackage::imports, ElementsAre(import)),
+ Field(&SynchronizationPackage::types, ElementsAre(Eq(objectType))),
+ Field(&SynchronizationPackage::sourceIds,
+ UnorderedElementsAre(qmlDirPathSourceId, qmltypesPathSourceId)),
+ Field(&SynchronizationPackage::fileStatuses,
+ UnorderedElementsAre(IsFileStatus(qmlDirPathSourceId, 21, 421),
+ IsFileStatus(qmltypesPathSourceId, 21, 421))))));
updater.update();
}
@@ -357,9 +365,7 @@ TEST_F(ProjectStorageUpdater, SynchronizeQmlTypesAreEmptyIfFileDoesNotChanged)
ON_CALL(fileSystemMock, contentAsQString(Eq(QString("/path/example.qmltypes"))))
.WillByDefault(Return(qmltypes));
ON_CALL(qmlTypesParserMock, parse(qmltypes, _, _, _))
- .WillByDefault([&](auto, auto &imports, auto &types, auto &sourceIds) {
- types.push_back(objectType);
- });
+ .WillByDefault([&](auto, auto &, auto &types, auto) { types.push_back(objectType); });
ON_CALL(fileSystemMock, fileStatus(Eq(qmltypesPathSourceId)))
.WillByDefault(Return(FileStatus{qmltypesPathSourceId, 2, 421}));
ON_CALL(fileSystemMock, fileStatus(Eq(qmltypes2PathSourceId)))
@@ -367,8 +373,7 @@ TEST_F(ProjectStorageUpdater, SynchronizeQmlTypesAreEmptyIfFileDoesNotChanged)
ON_CALL(fileSystemMock, fileStatus(Eq(qmlDirPathSourceId)))
.WillByDefault(Return(FileStatus{qmlDirPathSourceId, 2, 421}));
- EXPECT_CALL(projectStorageMock,
- synchronize(IsEmpty(), IsEmpty(), IsEmpty(), IsEmpty(), IsEmpty()));
+ EXPECT_CALL(projectStorageMock, synchronize(PackageIsEmpty()));
updater.update();
}
@@ -415,39 +420,40 @@ TEST_F(ProjectStorageUpdater, SynchronizeQmlDocuments)
"First.2.qml\nSecondType 2.1 OldSecond.qml\nSecondType 2.2 Second.qml\n"};
ON_CALL(fileSystemMock, contentAsQString(Eq(QString("/path/qmldir")))).WillByDefault(Return(qmldir));
- EXPECT_CALL(projectStorageMock,
- synchronize(ElementsAre(IsModule("Example", qmlDirPathSourceId)),
- UnorderedElementsAre(import1, import2, import3),
- UnorderedElementsAre(
- AllOf(IsStorageType(exampleModuleId,
- "First.qml",
- Storage::ImportedType{"Object"},
- TypeAccessSemantics::Reference,
- qmlDocumentSourceId1),
- Field(&Storage::Type::exportedTypes,
- ElementsAre(IsExportedType("FirstType", 1, 0)))),
- AllOf(IsStorageType(exampleModuleId,
- "First.2.qml",
- Storage::ImportedType{"Object2"},
- TypeAccessSemantics::Reference,
- qmlDocumentSourceId2),
- Field(&Storage::Type::exportedTypes,
- ElementsAre(IsExportedType("FirstType", 2, 2)))),
- AllOf(IsStorageType(exampleModuleId,
- "Second.qml",
- Storage::ImportedType{"Object3"},
- TypeAccessSemantics::Reference,
- qmlDocumentSourceId3),
- Field(&Storage::Type::exportedTypes,
- ElementsAre(IsExportedType("SecondType", 2, 2))))),
- UnorderedElementsAre(qmlDirPathSourceId,
- qmlDocumentSourceId1,
- qmlDocumentSourceId2,
- qmlDocumentSourceId3),
- UnorderedElementsAre(IsFileStatus(qmlDirPathSourceId, 21, 421),
- IsFileStatus(qmlDocumentSourceId1, 22, 12),
- IsFileStatus(qmlDocumentSourceId2, 22, 13),
- IsFileStatus(qmlDocumentSourceId3, 22, 14))));
+ EXPECT_CALL(
+ projectStorageMock,
+ synchronize(AllOf(
+ Field(&SynchronizationPackage::imports, UnorderedElementsAre(import1, import2, import3)),
+ Field(&SynchronizationPackage::types,
+ UnorderedElementsAre(
+ AllOf(IsStorageType("First.qml",
+ Storage::ImportedType{"Object"},
+ TypeAccessSemantics::Reference,
+ qmlDocumentSourceId1),
+ Field(&Storage::Type::exportedTypes,
+ ElementsAre(IsExportedType(exampleModuleId, "FirstType", 1, 0)))),
+ AllOf(IsStorageType("First.2.qml",
+ Storage::ImportedType{"Object2"},
+ TypeAccessSemantics::Reference,
+ qmlDocumentSourceId2),
+ Field(&Storage::Type::exportedTypes,
+ ElementsAre(IsExportedType(exampleModuleId, "FirstType", 2, 2)))),
+ AllOf(IsStorageType("Second.qml",
+ Storage::ImportedType{"Object3"},
+ TypeAccessSemantics::Reference,
+ qmlDocumentSourceId3),
+ Field(&Storage::Type::exportedTypes,
+ ElementsAre(IsExportedType(exampleModuleId, "SecondType", 2, 2)))))),
+ Field(&SynchronizationPackage::sourceIds,
+ UnorderedElementsAre(qmlDirPathSourceId,
+ qmlDocumentSourceId1,
+ qmlDocumentSourceId2,
+ qmlDocumentSourceId3)),
+ Field(&SynchronizationPackage::fileStatuses,
+ UnorderedElementsAre(IsFileStatus(qmlDirPathSourceId, 21, 421),
+ IsFileStatus(qmlDocumentSourceId1, 22, 12),
+ IsFileStatus(qmlDocumentSourceId2, 22, 13),
+ IsFileStatus(qmlDocumentSourceId3, 22, 14))))));
updater.update();
}
@@ -462,51 +468,28 @@ TEST_F(ProjectStorageUpdater, SynchronizeQmlDocumentsDontUpdateIfUpToDate)
EXPECT_CALL(
projectStorageMock,
- synchronize(ElementsAre(IsModule("Example", qmlDirPathSourceId)),
- UnorderedElementsAre(import1, import2),
- UnorderedElementsAre(AllOf(IsStorageType(exampleModuleId,
- "First.qml",
- Storage::ImportedType{"Object"},
- TypeAccessSemantics::Reference,
- qmlDocumentSourceId1),
- Field(&Storage::Type::exportedTypes,
- ElementsAre(IsExportedType("FirstType", 1, 0)))),
- AllOf(IsStorageType(exampleModuleId,
- "First.2.qml",
- Storage::ImportedType{"Object2"},
- TypeAccessSemantics::Reference,
- qmlDocumentSourceId2),
- Field(&Storage::Type::exportedTypes,
- ElementsAre(IsExportedType("FirstType", 2, 2))))),
- UnorderedElementsAre(qmlDirPathSourceId, qmlDocumentSourceId1, qmlDocumentSourceId2),
- UnorderedElementsAre(IsFileStatus(qmlDirPathSourceId, 21, 421),
- IsFileStatus(qmlDocumentSourceId1, 22, 12),
- IsFileStatus(qmlDocumentSourceId2, 22, 13))));
-
- updater.update();
-}
-
-TEST_F(ProjectStorageUpdater, SynchronizeModules)
-{
- SourceId qmlDirPathSourceId2 = sourcePathCache.sourceId("/path2/qmldir");
- ON_CALL(fileSystemMock, fileStatus(Eq(qmlDirPathSourceId2)))
- .WillByDefault(Return(FileStatus{qmlDirPathSourceId2, 22, 423}));
- ON_CALL(projectStorageMock, fetchFileStatus(Eq(qmlDirPathSourceId2)))
- .WillByDefault(Return(FileStatus{qmlDirPathSourceId2, 2, 421}));
- QString qmldir2{"module Example2\n"};
- ON_CALL(projectManagerMock, qtQmlDirs())
- .WillByDefault(Return(QStringList{"/path/qmldir", "/path2/qmldir"}));
- ON_CALL(fileSystemMock, contentAsQString(Eq(QString("/path2/qmldir")))).WillByDefault(Return(qmldir2));
-
- EXPECT_CALL(projectStorageMock,
- synchronize(UnorderedElementsAre(IsModule("Example", qmlDirPathSourceId),
- IsModule("Example2", qmlDirPathSourceId2)),
- _,
- _,
- _,
- UnorderedElementsAre(IsFileStatus(qmlDirPathSourceId, 21, 421),
- IsFileStatus(qmltypesPathSourceId, 21, 421),
- IsFileStatus(qmlDirPathSourceId2, 22, 423))));
+ synchronize(AllOf(
+ Field(&SynchronizationPackage::imports, UnorderedElementsAre(import1, import2)),
+ Field(&SynchronizationPackage::types,
+ UnorderedElementsAre(
+ AllOf(IsStorageType("First.qml",
+ Storage::ImportedType{"Object"},
+ TypeAccessSemantics::Reference,
+ qmlDocumentSourceId1),
+ Field(&Storage::Type::exportedTypes,
+ ElementsAre(IsExportedType(exampleModuleId, "FirstType", 1, 0)))),
+ AllOf(IsStorageType("First.2.qml",
+ Storage::ImportedType{"Object2"},
+ TypeAccessSemantics::Reference,
+ qmlDocumentSourceId2),
+ Field(&Storage::Type::exportedTypes,
+ ElementsAre(IsExportedType(exampleModuleId, "FirstType", 2, 2)))))),
+ Field(&SynchronizationPackage::sourceIds,
+ UnorderedElementsAre(qmlDirPathSourceId, qmlDocumentSourceId1, qmlDocumentSourceId2)),
+ Field(&SynchronizationPackage::fileStatuses,
+ UnorderedElementsAre(IsFileStatus(qmlDirPathSourceId, 21, 421),
+ IsFileStatus(qmlDocumentSourceId1, 22, 12),
+ IsFileStatus(qmlDocumentSourceId2, 22, 13))))));
updater.update();
}
diff --git a/tests/unit/unittest/qmldocumentparser-test.cpp b/tests/unit/unittest/qmldocumentparser-test.cpp
new file mode 100644
index 0000000000..451003ba33
--- /dev/null
+++ b/tests/unit/unittest/qmldocumentparser-test.cpp
@@ -0,0 +1,247 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 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 <sqlitedatabase.h>
+
+#include <projectstorage/projectstorage.h>
+#include <projectstorage/qmldocumentparser.h>
+#include <projectstorage/sourcepathcache.h>
+
+namespace {
+
+namespace Storage = QmlDesigner::Storage;
+using QmlDesigner::ModuleId;
+using QmlDesigner::SourceContextId;
+using QmlDesigner::SourceId;
+
+MATCHER_P(HasPrototype, prototype, std::string(negation ? "isn't " : "is ") + PrintToString(prototype))
+{
+ const Storage::Type &type = arg;
+
+ return Storage::ImportedTypeName{prototype} == type.prototype;
+}
+
+MATCHER_P3(IsPropertyDeclaration,
+ name,
+ typeName,
+ traits,
+ std::string(negation ? "isn't " : "is ")
+ + PrintToString(Storage::PropertyDeclaration{name, typeName, traits}))
+{
+ const Storage::PropertyDeclaration &propertyDeclaration = arg;
+
+ return propertyDeclaration.name == name
+ && Storage::ImportedTypeName{typeName} == propertyDeclaration.typeName
+ && propertyDeclaration.traits == traits;
+}
+
+MATCHER_P2(IsFunctionDeclaration,
+ name,
+ returnTypeName,
+ std::string(negation ? "isn't " : "is ")
+ + PrintToString(Storage::FunctionDeclaration{name, returnTypeName}))
+{
+ const Storage::FunctionDeclaration &declaration = arg;
+
+ return declaration.name == name && declaration.returnTypeName == returnTypeName;
+}
+
+MATCHER_P(IsSignalDeclaration,
+ name,
+ std::string(negation ? "isn't " : "is ") + PrintToString(Storage::SignalDeclaration{name}))
+{
+ const Storage::SignalDeclaration &declaration = arg;
+
+ return declaration.name == name;
+}
+
+MATCHER_P2(IsParameter,
+ name,
+ typeName,
+ std::string(negation ? "isn't " : "is ")
+ + PrintToString(Storage::ParameterDeclaration{name, typeName}))
+{
+ const Storage::ParameterDeclaration &declaration = arg;
+
+ return declaration.name == name && declaration.typeName == typeName;
+}
+
+MATCHER_P(IsEnumeration,
+ name,
+ std::string(negation ? "isn't " : "is ")
+ + PrintToString(Storage::EnumerationDeclaration{name, {}}))
+{
+ const Storage::EnumerationDeclaration &declaration = arg;
+
+ return declaration.name == name;
+}
+
+MATCHER_P(IsEnumerator,
+ name,
+ std::string(negation ? "isn't " : "is ")
+ + PrintToString(Storage::EnumeratorDeclaration{name}))
+{
+ const Storage::EnumeratorDeclaration &declaration = arg;
+
+ return declaration.name == name && !declaration.hasValue;
+}
+
+MATCHER_P2(IsEnumerator,
+ name,
+ value,
+ std::string(negation ? "isn't " : "is ")
+ + PrintToString(Storage::EnumeratorDeclaration{name, value, true}))
+{
+ const Storage::EnumeratorDeclaration &declaration = arg;
+
+ return declaration.name == name && declaration.value == value && declaration.hasValue;
+}
+
+class QmlDocumentParser : public ::testing::Test
+{
+public:
+protected:
+ Sqlite::Database database{":memory:", Sqlite::JournalMode::Memory};
+ QmlDesigner::ProjectStorage<Sqlite::Database> storage{database, database.isInitialized()};
+ QmlDesigner::SourcePathCache<QmlDesigner::ProjectStorage<Sqlite::Database>> sourcePathCache{
+ storage};
+ QmlDesigner::QmlDocumentParser parser{sourcePathCache, storage};
+ Storage::Imports imports;
+ SourceId qmlFileSourceId{sourcePathCache.sourceId("path/to/qmlfile.qml")};
+ SourceContextId qmlFileSourceContextId{sourcePathCache.sourceContextId(qmlFileSourceId)};
+ SourceId directorySourceId{sourcePathCache.sourceId("path/to/.")};
+ ModuleId directoryModuleId{&directorySourceId};
+};
+
+TEST_F(QmlDocumentParser, Prototype)
+{
+ auto type = parser.parse("Example{}", imports, qmlFileSourceId, qmlFileSourceContextId);
+
+ ASSERT_THAT(type, HasPrototype(Storage::ImportedType("Example")));
+}
+
+TEST_F(QmlDocumentParser, DISABLED_QualifiedPrototype)
+{
+ auto exampleModuleId = storage.moduleId("Example");
+ auto type = parser.parse("import Example as Example\n Example.Item{}",
+ imports,
+ qmlFileSourceId,
+ qmlFileSourceContextId);
+
+ ASSERT_THAT(type,
+ HasPrototype(Storage::QualifiedImportedType(
+ "Item", Storage::Import{exampleModuleId, Storage::Version{}, qmlFileSourceId})));
+}
+
+TEST_F(QmlDocumentParser, Properties)
+{
+ auto type = parser.parse("Example{\n property int foo\n}",
+ imports,
+ qmlFileSourceId,
+ qmlFileSourceContextId);
+
+ ASSERT_THAT(type.propertyDeclarations,
+ UnorderedElementsAre(IsPropertyDeclaration("foo",
+ Storage::ImportedType{"int"},
+ Storage::PropertyDeclarationTraits::None)));
+}
+
+TEST_F(QmlDocumentParser, DISABLED_Imports)
+{
+ ModuleId fooDirectoryModuleId = storage.moduleId("path/to/foo/.");
+ ModuleId qmlModuleId = storage.moduleId("QML");
+ ModuleId qtQmlModuleId = storage.moduleId("QtQml");
+ ModuleId qtQuickModuleId = storage.moduleId("QtQuick");
+ auto type = parser.parse("import QtQuick\n import \"../foo\"\nExample{}",
+ imports,
+ qmlFileSourceId,
+ qmlFileSourceContextId);
+
+ ASSERT_THAT(imports,
+ UnorderedElementsAre(
+ Storage::Import{directoryModuleId, Storage::Version{}, qmlFileSourceId},
+ Storage::Import{fooDirectoryModuleId, Storage::Version{}, qmlFileSourceId},
+ Storage::Import{qmlModuleId, Storage::Version{1, 0}, qmlFileSourceId},
+ Storage::Import{qtQmlModuleId, Storage::Version{6, 0}, qmlFileSourceId},
+ Storage::Import{qtQuickModuleId, Storage::Version{}, qmlFileSourceId}));
+}
+
+TEST_F(QmlDocumentParser, Functions)
+{
+ auto type = parser.parse(
+ "Example{\n function someScript(x, y) {}\n function otherFunction() {}\n}",
+ imports,
+ qmlFileSourceId,
+ qmlFileSourceContextId);
+
+ ASSERT_THAT(type.functionDeclarations,
+ UnorderedElementsAre(AllOf(IsFunctionDeclaration("otherFunction", ""),
+ Field(&Storage::FunctionDeclaration::parameters, IsEmpty())),
+ AllOf(IsFunctionDeclaration("someScript", ""),
+ Field(&Storage::FunctionDeclaration::parameters,
+ ElementsAre(IsParameter("x", ""),
+ IsParameter("y", ""))))));
+}
+
+TEST_F(QmlDocumentParser, Signals)
+{
+ auto type = parser.parse("Example{\n signal someSignal(int x, real y)\n signal signal2()\n}",
+ imports,
+ qmlFileSourceId,
+ qmlFileSourceContextId);
+
+ ASSERT_THAT(type.signalDeclarations,
+ UnorderedElementsAre(AllOf(IsSignalDeclaration("someSignal"),
+ Field(&Storage::SignalDeclaration::parameters,
+ ElementsAre(IsParameter("x", "int"),
+ IsParameter("y", "real")))),
+ AllOf(IsSignalDeclaration("signal2"),
+ Field(&Storage::SignalDeclaration::parameters, IsEmpty()))));
+}
+
+TEST_F(QmlDocumentParser, Enumeration)
+{
+ auto type = parser.parse("Example{\n enum Color{red, green, blue=10, white}\n enum "
+ "State{On,Off}\n}",
+ imports,
+ qmlFileSourceId,
+ qmlFileSourceContextId);
+
+ ASSERT_THAT(type.enumerationDeclarations,
+ UnorderedElementsAre(
+ AllOf(IsEnumeration("Color"),
+ Field(&Storage::EnumerationDeclaration::enumeratorDeclarations,
+ ElementsAre(IsEnumerator("red", 0),
+ IsEnumerator("green", 1),
+ IsEnumerator("blue", 10),
+ IsEnumerator("white", 11)))),
+ AllOf(IsEnumeration("State"),
+ Field(&Storage::EnumerationDeclaration::enumeratorDeclarations,
+ ElementsAre(IsEnumerator("On", 0), IsEnumerator("Off", 1))))));
+}
+
+} // namespace
diff --git a/tests/unit/unittest/qmltypesparser-test.cpp b/tests/unit/unittest/qmltypesparser-test.cpp
new file mode 100644
index 0000000000..9de60a1807
--- /dev/null
+++ b/tests/unit/unittest/qmltypesparser-test.cpp
@@ -0,0 +1,397 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 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 <sqlitedatabase.h>
+
+#include <projectstorage/projectstorage.h>
+#include <projectstorage/projectstoragetypes.h>
+#include <projectstorage/qmltypesparser.h>
+#include <projectstorage/sourcepathcache.h>
+
+namespace {
+
+namespace Storage = QmlDesigner::Storage;
+using QmlDesigner::ModuleId;
+using QmlDesigner::SourceContextId;
+using QmlDesigner::SourceId;
+
+MATCHER_P3(IsImport,
+ moduleId,
+ version,
+ sourceId,
+ std::string(negation ? "isn't " : "is ")
+ + PrintToString(Storage::Import{moduleId, version, sourceId}))
+{
+ const Storage::Import &import = arg;
+
+ return import.moduleId == moduleId && import.version == version && import.sourceId == sourceId;
+}
+
+MATCHER_P(HasPrototype, prototype, std::string(negation ? "isn't " : "is ") + PrintToString(prototype))
+{
+ const Storage::Type &type = arg;
+
+ return Storage::ImportedTypeName{prototype} == type.prototype;
+}
+
+MATCHER_P4(IsType,
+ typeName,
+ prototype,
+ accessSemantics,
+ sourceId,
+ std::string(negation ? "isn't " : "is ")
+ + PrintToString(Storage::Type{typeName, prototype, accessSemantics, sourceId}))
+{
+ const Storage::Type &type = arg;
+
+ return type.typeName == typeName && type.prototype == Storage::ImportedTypeName{prototype}
+ && type.accessSemantics == accessSemantics && type.sourceId == sourceId;
+}
+
+MATCHER_P3(IsPropertyDeclaration,
+ name,
+ typeName,
+ traits,
+ std::string(negation ? "isn't " : "is ")
+ + PrintToString(Storage::PropertyDeclaration{name, typeName, traits}))
+{
+ const Storage::PropertyDeclaration &propertyDeclaration = arg;
+
+ return propertyDeclaration.name == name
+ && Storage::ImportedTypeName{typeName} == propertyDeclaration.typeName
+ && propertyDeclaration.traits == traits
+ && propertyDeclaration.kind == Storage::PropertyKind::Property;
+}
+
+MATCHER_P2(IsFunctionDeclaration,
+ name,
+ returnTypeName,
+ std::string(negation ? "isn't " : "is ")
+ + PrintToString(Storage::FunctionDeclaration{name, returnTypeName}))
+{
+ const Storage::FunctionDeclaration &declaration = arg;
+
+ return declaration.name == name && declaration.returnTypeName == returnTypeName;
+}
+
+MATCHER_P(IsSignalDeclaration,
+ name,
+ std::string(negation ? "isn't " : "is ") + PrintToString(Storage::SignalDeclaration{name}))
+{
+ const Storage::SignalDeclaration &declaration = arg;
+
+ return declaration.name == name;
+}
+
+MATCHER_P2(IsParameter,
+ name,
+ typeName,
+ std::string(negation ? "isn't " : "is ")
+ + PrintToString(Storage::ParameterDeclaration{name, typeName}))
+{
+ const Storage::ParameterDeclaration &declaration = arg;
+
+ return declaration.name == name && declaration.typeName == typeName;
+}
+
+MATCHER_P(IsEnumeration,
+ name,
+ std::string(negation ? "isn't " : "is ")
+ + PrintToString(Storage::EnumerationDeclaration{name, {}}))
+{
+ const Storage::EnumerationDeclaration &declaration = arg;
+
+ return declaration.name == name;
+}
+
+MATCHER_P(IsEnumerator,
+ name,
+ std::string(negation ? "isn't " : "is ")
+ + PrintToString(Storage::EnumeratorDeclaration{name}))
+{
+ const Storage::EnumeratorDeclaration &declaration = arg;
+
+ return declaration.name == name && !declaration.hasValue;
+}
+
+MATCHER_P2(IsEnumerator,
+ name,
+ value,
+ std::string(negation ? "isn't " : "is ")
+ + PrintToString(Storage::EnumeratorDeclaration{name, value, true}))
+{
+ const Storage::EnumeratorDeclaration &declaration = arg;
+
+ return declaration.name == name && declaration.value == value && declaration.hasValue;
+}
+
+MATCHER_P3(IsExportedType,
+ moduleId,
+ name,
+ version,
+ std::string(negation ? "isn't " : "is ")
+ + PrintToString(Storage::ExportedType{moduleId, name, version}))
+{
+ const Storage::ExportedType &type = arg;
+
+ return type.name == name && type.moduleId == moduleId && type.version == version;
+}
+
+class QmlTypesParser : public ::testing::Test
+{
+public:
+protected:
+ Sqlite::Database database{":memory:", Sqlite::JournalMode::Memory};
+ QmlDesigner::ProjectStorage<Sqlite::Database> storage{database, database.isInitialized()};
+ QmlDesigner::SourcePathCache<QmlDesigner::ProjectStorage<Sqlite::Database>> sourcePathCache{
+ storage};
+ QmlDesigner::QmlTypesParser parser{sourcePathCache, storage};
+ Storage::Imports imports;
+ Storage::Types types;
+ SourceId qmltypesFileSourceId{sourcePathCache.sourceId("path/to/types.qmltypes")};
+ QmlDesigner::Storage::ProjectData projectData{storage.moduleId("QtQml-cppnative"),
+ qmltypesFileSourceId};
+ SourceContextId qmltypesFileSourceContextId{sourcePathCache.sourceContextId(qmltypesFileSourceId)};
+ ModuleId directoryModuleId{storage.moduleId("path/to/")};
+};
+
+TEST_F(QmlTypesParser, Imports)
+{
+ QString source{R"(import QtQuick.tooling 1.2
+ Module{
+ dependencies:
+ ["QtQuick 2.15", "QtQuick.Window 2.1", "QtFoo 6"]})"};
+
+ parser.parse(source, imports, types, projectData);
+
+ ASSERT_THAT(
+ imports,
+ UnorderedElementsAre(
+ IsImport(storage.moduleId("QML"), Storage::Version{}, qmltypesFileSourceId),
+ IsImport(storage.moduleId("QtQml-cppnative"), Storage::Version{}, qmltypesFileSourceId),
+ IsImport(storage.moduleId("QtQuick-cppnative"), Storage::Version{2, 15}, qmltypesFileSourceId),
+ IsImport(storage.moduleId("QtQuick.Window-cppnative"),
+ Storage::Version{2, 1},
+ qmltypesFileSourceId),
+ IsImport(storage.moduleId("QtFoo-cppnative"), Storage::Version{6}, qmltypesFileSourceId)));
+}
+
+TEST_F(QmlTypesParser, Types)
+{
+ QString source{R"(import QtQuick.tooling 1.2
+ Module{
+ Component { name: "QObject"}
+ Component { name: "QQmlComponent"
+ prototype: "QObject"}})"};
+
+ parser.parse(source, imports, types, projectData);
+
+ ASSERT_THAT(types,
+ UnorderedElementsAre(IsType("QObject",
+ Storage::NativeType{},
+ Storage::TypeAccessSemantics::Reference,
+ qmltypesFileSourceId),
+ IsType("QQmlComponent",
+ Storage::NativeType{"QObject"},
+ Storage::TypeAccessSemantics::Reference,
+ qmltypesFileSourceId)));
+}
+
+TEST_F(QmlTypesParser, ExportedTypes)
+{
+ QString source{R"(import QtQuick.tooling 1.2
+ Module{
+ Component { name: "QObject"
+ exports: ["QML/QtObject 1.0", "QtQml/QtObject 2.1"]
+ }})"};
+ ModuleId qmlModuleId = storage.moduleId("QML");
+ ModuleId qtQmlModuleId = storage.moduleId("QtQml");
+ ModuleId qtQmlNativeModuleId = storage.moduleId("QtQml-cppnative");
+
+ parser.parse(source, imports, types, projectData);
+
+ ASSERT_THAT(types,
+ ElementsAre(Field(
+ &Storage::Type::exportedTypes,
+ ElementsAre(IsExportedType(qmlModuleId, "QtObject", Storage::Version{1, 0}),
+ IsExportedType(qtQmlModuleId, "QtObject", Storage::Version{2, 1}),
+ IsExportedType(qtQmlNativeModuleId, "QObject", Storage::Version{})))));
+}
+
+TEST_F(QmlTypesParser, Properties)
+{
+ QString source{R"(import QtQuick.tooling 1.2
+ Module{
+ Component { name: "QObject"
+ Property { name: "objectName"; type: "string" }
+ Property { name: "target"; type: "QObject"; isPointer: true }
+ Property { name: "progress"; type: "double"; isReadonly: true }
+ Property { name: "targets"; type: "QQuickItem"; isList: true; isReadonly: true; isPointer: true }
+ }})"};
+
+ parser.parse(source, imports, types, projectData);
+
+ ASSERT_THAT(types,
+ ElementsAre(Field(
+ &Storage::Type::propertyDeclarations,
+ UnorderedElementsAre(
+ IsPropertyDeclaration("objectName",
+ Storage::NativeType{"string"},
+ Storage::PropertyDeclarationTraits::None),
+ IsPropertyDeclaration("target",
+ Storage::NativeType{"QObject"},
+ Storage::PropertyDeclarationTraits::IsPointer),
+ IsPropertyDeclaration("progress",
+ Storage::NativeType{"double"},
+ Storage::PropertyDeclarationTraits::IsReadOnly),
+ IsPropertyDeclaration("targets",
+ Storage::NativeType{"QQuickItem"},
+ Storage::PropertyDeclarationTraits::IsReadOnly
+ | Storage::PropertyDeclarationTraits::IsList
+ | Storage::PropertyDeclarationTraits::IsPointer)))));
+}
+
+TEST_F(QmlTypesParser, Functions)
+{
+ QString source{R"(import QtQuick.tooling 1.2
+ Module{
+ Component { name: "QObject"
+ Method { name: "movieUpdate" }
+ Method {
+ name: "advance"
+ Parameter { name: "frames"; type: "int" }
+ Parameter { name: "fps"; type: "double" }
+ }
+ Method {
+ name: "isImageLoading"
+ type: "bool"
+ Parameter { name: "url"; type: "QUrl" }
+ }
+ Method {
+ name: "getContext"
+ Parameter { name: "args"; type: "QQmlV4Function"; isPointer: true }
+ }
+ }})"};
+
+ parser.parse(source, imports, types, projectData);
+
+ ASSERT_THAT(types,
+ ElementsAre(
+ Field(&Storage::Type::functionDeclarations,
+ UnorderedElementsAre(
+ AllOf(IsFunctionDeclaration("advance", ""),
+ Field(&Storage::FunctionDeclaration::parameters,
+ UnorderedElementsAre(IsParameter("frames", "int"),
+ IsParameter("fps", "double")))),
+ AllOf(IsFunctionDeclaration("isImageLoading", "bool"),
+ Field(&Storage::FunctionDeclaration::parameters,
+ UnorderedElementsAre(IsParameter("url", "QUrl")))),
+ AllOf(IsFunctionDeclaration("getContext", ""),
+ Field(&Storage::FunctionDeclaration::parameters,
+ UnorderedElementsAre(IsParameter("args", "QQmlV4Function")))),
+ AllOf(IsFunctionDeclaration("movieUpdate", ""),
+ Field(&Storage::FunctionDeclaration::parameters, IsEmpty()))))));
+}
+
+TEST_F(QmlTypesParser, Signals)
+{
+ QString source{R"(import QtQuick.tooling 1.2
+ Module{
+ Component { name: "QObject"
+ Method { name: "movieUpdate" }
+ Signal {
+ name: "advance"
+ Parameter { name: "frames"; type: "int" }
+ Parameter { name: "fps"; type: "double" }
+ }
+ Signal {
+ name: "isImageLoading"
+ Parameter { name: "url"; type: "QUrl" }
+ }
+ Signal {
+ name: "getContext"
+ Parameter { name: "args"; type: "QQmlV4Function"; isPointer: true }
+ }
+ }})"};
+
+ parser.parse(source, imports, types, projectData);
+
+ ASSERT_THAT(types,
+ ElementsAre(Field(&Storage::Type::signalDeclarations,
+ UnorderedElementsAre(
+ AllOf(IsSignalDeclaration("advance"),
+ Field(&Storage::SignalDeclaration::parameters,
+ UnorderedElementsAre(IsParameter("frames", "int"),
+ IsParameter("fps", "double")))),
+ AllOf(IsSignalDeclaration("isImageLoading"),
+ Field(&Storage::SignalDeclaration::parameters,
+ UnorderedElementsAre(IsParameter("url", "QUrl")))),
+ AllOf(IsSignalDeclaration("getContext"),
+ Field(&Storage::SignalDeclaration::parameters,
+ UnorderedElementsAre(
+ IsParameter("args", "QQmlV4Function"))))))));
+}
+
+TEST_F(QmlTypesParser, Enumerations)
+{
+ QString source{R"(import QtQuick.tooling 1.2
+ Module{
+ Component { name: "QObject"
+ Enum {
+ name: "NamedColorSpace"
+ values: [
+ "Unknown",
+ "SRgb",
+ "AdobeRgb",
+ "DisplayP3",
+ ]
+ }
+ Enum {
+ name: "VerticalLayoutDirection"
+ values: ["TopToBottom", "BottomToTop"]
+ }
+ }})"};
+
+ parser.parse(source, imports, types, projectData);
+
+ ASSERT_THAT(types,
+ ElementsAre(
+ Field(&Storage::Type::enumerationDeclarations,
+ UnorderedElementsAre(
+ AllOf(IsEnumeration("NamedColorSpace"),
+ Field(&Storage::EnumerationDeclaration::enumeratorDeclarations,
+ UnorderedElementsAre(IsEnumerator("Unknown"),
+ IsEnumerator("SRgb"),
+ IsEnumerator("AdobeRgb"),
+ IsEnumerator("DisplayP3")))),
+ AllOf(IsEnumeration("VerticalLayoutDirection"),
+ Field(&Storage::EnumerationDeclaration::enumeratorDeclarations,
+ UnorderedElementsAre(IsEnumerator("TopToBottom"),
+ IsEnumerator("BottomToTop"))))))));
+}
+
+} // namespace
diff --git a/tests/unit/unittest/qmltypesparsermock.h b/tests/unit/unittest/qmltypesparsermock.h
index 337c0f05ff..6cf5271379 100644
--- a/tests/unit/unittest/qmltypesparsermock.h
+++ b/tests/unit/unittest/qmltypesparsermock.h
@@ -37,6 +37,6 @@ public:
(const QString &sourceContent,
QmlDesigner::Storage::Imports &imports,
QmlDesigner::Storage::Types &types,
- QmlDesigner::SourceIds &sourceIds),
+ const QmlDesigner::Storage::ProjectData &projectData),
(override));
};