aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-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.cpp38
-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
315 files changed, 6149 insertions, 2207 deletions
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/src/libs/utils/threadutils.cpp b/src/libs/utils/threadutils.cpp
new file mode 100644
index 0000000000..7d10199c4a
--- /dev/null
+++ b/src/libs/utils/threadutils.cpp
@@ -0,0 +1,38 @@
+/****************************************************************************
+**
+** 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 "threadutils.h"
+
+#include <QCoreApplication>
+#include <QThread>
+
+namespace Utils {
+
+bool isMainThread()
+{
+ return QThread::currentThread() == qApp->thread();
+}
+
+} // 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